]> granicus.if.org Git - postgresql/blob - src/backend/commands/tablecmds.c
Restructure operator classes to allow improved handling of cross-data-type
[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-2006, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.207 2006/12/23 00:43:09 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "access/reloptions.h"
20 #include "access/xact.h"
21 #include "catalog/catalog.h"
22 #include "catalog/dependency.h"
23 #include "catalog/heap.h"
24 #include "catalog/index.h"
25 #include "catalog/indexing.h"
26 #include "catalog/namespace.h"
27 #include "catalog/pg_constraint.h"
28 #include "catalog/pg_depend.h"
29 #include "catalog/pg_inherits.h"
30 #include "catalog/pg_namespace.h"
31 #include "catalog/pg_trigger.h"
32 #include "catalog/pg_type.h"
33 #include "catalog/toasting.h"
34 #include "commands/cluster.h"
35 #include "commands/defrem.h"
36 #include "commands/tablecmds.h"
37 #include "commands/tablespace.h"
38 #include "commands/trigger.h"
39 #include "commands/typecmds.h"
40 #include "executor/executor.h"
41 #include "miscadmin.h"
42 #include "nodes/makefuncs.h"
43 #include "optimizer/clauses.h"
44 #include "optimizer/plancat.h"
45 #include "optimizer/prep.h"
46 #include "parser/analyze.h"
47 #include "parser/gramparse.h"
48 #include "parser/parse_clause.h"
49 #include "parser/parse_coerce.h"
50 #include "parser/parse_expr.h"
51 #include "parser/parse_oper.h"
52 #include "parser/parse_relation.h"
53 #include "parser/parse_type.h"
54 #include "parser/parser.h"
55 #include "rewrite/rewriteHandler.h"
56 #include "storage/smgr.h"
57 #include "utils/acl.h"
58 #include "utils/builtins.h"
59 #include "utils/fmgroids.h"
60 #include "utils/inval.h"
61 #include "utils/lsyscache.h"
62 #include "utils/memutils.h"
63 #include "utils/relcache.h"
64 #include "utils/syscache.h"
65
66
67 /*
68  * ON COMMIT action list
69  */
70 typedef struct OnCommitItem
71 {
72         Oid                     relid;                  /* relid of relation */
73         OnCommitAction oncommit;        /* what to do at end of xact */
74
75         /*
76          * If this entry was created during the current transaction,
77          * creating_subid is the ID of the creating subxact; if created in a prior
78          * transaction, creating_subid is zero.  If deleted during the current
79          * transaction, deleting_subid is the ID of the deleting subxact; if no
80          * deletion request is pending, deleting_subid is zero.
81          */
82         SubTransactionId creating_subid;
83         SubTransactionId deleting_subid;
84 } OnCommitItem;
85
86 static List *on_commits = NIL;
87
88
89 /*
90  * State information for ALTER TABLE
91  *
92  * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
93  * structs, one for each table modified by the operation (the named table
94  * plus any child tables that are affected).  We save lists of subcommands
95  * to apply to this table (possibly modified by parse transformation steps);
96  * these lists will be executed in Phase 2.  If a Phase 3 step is needed,
97  * necessary information is stored in the constraints and newvals lists.
98  *
99  * Phase 2 is divided into multiple passes; subcommands are executed in
100  * a pass determined by subcommand type.
101  */
102
103 #define AT_PASS_DROP                    0               /* DROP (all flavors) */
104 #define AT_PASS_ALTER_TYPE              1               /* ALTER COLUMN TYPE */
105 #define AT_PASS_OLD_INDEX               2               /* re-add existing indexes */
106 #define AT_PASS_OLD_CONSTR              3               /* re-add existing constraints */
107 #define AT_PASS_COL_ATTRS               4               /* set other column attributes */
108 /* We could support a RENAME COLUMN pass here, but not currently used */
109 #define AT_PASS_ADD_COL                 5               /* ADD COLUMN */
110 #define AT_PASS_ADD_INDEX               6               /* ADD indexes */
111 #define AT_PASS_ADD_CONSTR              7               /* ADD constraints, defaults */
112 #define AT_PASS_MISC                    8               /* other stuff */
113 #define AT_NUM_PASSES                   9
114
115 typedef struct AlteredTableInfo
116 {
117         /* Information saved before any work commences: */
118         Oid                     relid;                  /* Relation to work on */
119         char            relkind;                /* Its relkind */
120         TupleDesc       oldDesc;                /* Pre-modification tuple descriptor */
121         /* Information saved by Phase 1 for Phase 2: */
122         List       *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
123         /* Information saved by Phases 1/2 for Phase 3: */
124         List       *constraints;        /* List of NewConstraint */
125         List       *newvals;            /* List of NewColumnValue */
126         bool            new_notnull;    /* T if we added new NOT NULL constraints */
127         Oid                     newTableSpace;  /* new tablespace; 0 means no change */
128         /* Objects to rebuild after completing ALTER TYPE operations */
129         List       *changedConstraintOids;      /* OIDs of constraints to rebuild */
130         List       *changedConstraintDefs;      /* string definitions of same */
131         List       *changedIndexOids;           /* OIDs of indexes to rebuild */
132         List       *changedIndexDefs;           /* string definitions of same */
133 } AlteredTableInfo;
134
135 /* Struct describing one new constraint to check in Phase 3 scan */
136 /* Note: new NOT NULL constraints are handled elsewhere */
137 typedef struct NewConstraint
138 {
139         char       *name;                       /* Constraint name, or NULL if none */
140         ConstrType      contype;                /* CHECK or FOREIGN */
141         Oid                     refrelid;               /* PK rel, if FOREIGN */
142         Node       *qual;                       /* Check expr or FkConstraint struct */
143         List       *qualstate;          /* Execution state for CHECK */
144 } NewConstraint;
145
146 /*
147  * Struct describing one new column value that needs to be computed during
148  * Phase 3 copy (this could be either a new column with a non-null default, or
149  * a column that we're changing the type of).  Columns without such an entry
150  * are just copied from the old table during ATRewriteTable.  Note that the
151  * expr is an expression over *old* table values.
152  */
153 typedef struct NewColumnValue
154 {
155         AttrNumber      attnum;                 /* which column */
156         Expr       *expr;                       /* expression to compute */
157         ExprState  *exprstate;          /* execution state */
158 } NewColumnValue;
159
160
161 static void truncate_check_rel(Relation rel);
162 static List *MergeAttributes(List *schema, List *supers, bool istemp,
163                                 List **supOids, List **supconstr, int *supOidCount);
164 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
165 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
166 static void add_nonduplicate_constraint(Constraint *cdef,
167                                                                                 ConstrCheck *check, int *ncheck);
168 static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
169 static void StoreCatalogInheritance(Oid relationId, List *supers);
170 static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
171                                                  int16 seqNumber, Relation inhRelation);
172 static int      findAttrByName(const char *attributeName, List *schema);
173 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
174 static void AlterIndexNamespaces(Relation classRel, Relation rel,
175                                          Oid oldNspOid, Oid newNspOid);
176 static void AlterSeqNamespaces(Relation classRel, Relation rel,
177                                    Oid oldNspOid, Oid newNspOid,
178                                    const char *newNspName);
179 static int transformColumnNameList(Oid relId, List *colList,
180                                                 int16 *attnums, Oid *atttypids);
181 static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
182                                                    List **attnamelist,
183                                                    int16 *attnums, Oid *atttypids,
184                                                    Oid *opclasses);
185 static Oid transformFkeyCheckAttrs(Relation pkrel,
186                                                 int numattrs, int16 *attnums,
187                                                 Oid *opclasses);
188 static void validateForeignKeyConstraint(FkConstraint *fkconstraint,
189                                                          Relation rel, Relation pkrel);
190 static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
191                                                  Oid constrOid);
192 static char *fkMatchTypeToString(char match_type);
193 static void ATController(Relation rel, List *cmds, bool recurse);
194 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
195                   bool recurse, bool recursing);
196 static void ATRewriteCatalogs(List **wqueue);
197 static void ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd);
198 static void ATRewriteTables(List **wqueue);
199 static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap);
200 static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
201 static void ATSimplePermissions(Relation rel, bool allowView);
202 static void ATSimplePermissionsRelationOrIndex(Relation rel);
203 static void ATSimpleRecursion(List **wqueue, Relation rel,
204                                   AlterTableCmd *cmd, bool recurse);
205 static void ATOneLevelRecursion(List **wqueue, Relation rel,
206                                         AlterTableCmd *cmd);
207 static void find_composite_type_dependencies(Oid typeOid,
208                                                                  const char *origTblName);
209 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
210                                 AlterTableCmd *cmd);
211 static void ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
212                                 ColumnDef *colDef);
213 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
214 static void ATExecDropNotNull(Relation rel, const char *colName);
215 static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
216                                  const char *colName);
217 static void ATExecColumnDefault(Relation rel, const char *colName,
218                                         Node *newDefault);
219 static void ATPrepSetStatistics(Relation rel, const char *colName,
220                                         Node *flagValue);
221 static void ATExecSetStatistics(Relation rel, const char *colName,
222                                         Node *newValue);
223 static void ATExecSetStorage(Relation rel, const char *colName,
224                                  Node *newValue);
225 static void ATExecDropColumn(Relation rel, const char *colName,
226                                  DropBehavior behavior,
227                                  bool recurse, bool recursing);
228 static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
229                            IndexStmt *stmt, bool is_rebuild);
230 static void ATExecAddConstraint(AlteredTableInfo *tab, Relation rel,
231                                         Node *newConstraint);
232 static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
233                                                   FkConstraint *fkconstraint);
234 static void ATPrepDropConstraint(List **wqueue, Relation rel,
235                                          bool recurse, AlterTableCmd *cmd);
236 static void ATExecDropConstraint(Relation rel, const char *constrName,
237                                          DropBehavior behavior, bool quiet);
238 static void ATPrepAlterColumnType(List **wqueue,
239                                           AlteredTableInfo *tab, Relation rel,
240                                           bool recurse, bool recursing,
241                                           AlterTableCmd *cmd);
242 static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
243                                           const char *colName, TypeName *typename);
244 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
245 static void ATPostAlterTypeParse(char *cmd, List **wqueue);
246 static void change_owner_recurse_to_sequences(Oid relationOid,
247                                                                   Oid newOwnerId);
248 static void ATExecClusterOn(Relation rel, const char *indexName);
249 static void ATExecDropCluster(Relation rel);
250 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
251                                         char *tablespacename);
252 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace);
253 static void ATExecSetRelOptions(Relation rel, List *defList, bool isReset);
254 static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
255                                                    bool enable, bool skip_system);
256 static void ATExecAddInherit(Relation rel, RangeVar *parent);
257 static void ATExecDropInherit(Relation rel, RangeVar *parent);
258 static void copy_relation_data(Relation rel, SMgrRelation dst);
259 static void update_ri_trigger_args(Oid relid,
260                                            const char *oldname,
261                                            const char *newname,
262                                            bool fk_scan,
263                                            bool update_relname);
264
265
266 /* ----------------------------------------------------------------
267  *              DefineRelation
268  *                              Creates a new relation.
269  *
270  * If successful, returns the OID of the new relation.
271  * ----------------------------------------------------------------
272  */
273 Oid
274 DefineRelation(CreateStmt *stmt, char relkind)
275 {
276         char            relname[NAMEDATALEN];
277         Oid                     namespaceId;
278         List       *schema = stmt->tableElts;
279         Oid                     relationId;
280         Oid                     tablespaceId;
281         Relation        rel;
282         TupleDesc       descriptor;
283         List       *inheritOids;
284         List       *old_constraints;
285         bool            localHasOids;
286         int                     parentOidCount;
287         List       *rawDefaults;
288         Datum           reloptions;
289         ListCell   *listptr;
290         AttrNumber      attnum;
291
292         /*
293          * Truncate relname to appropriate length (probably a waste of time, as
294          * parser should have done this already).
295          */
296         StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
297
298         /*
299          * Check consistency of arguments
300          */
301         if (stmt->oncommit != ONCOMMIT_NOOP && !stmt->relation->istemp)
302                 ereport(ERROR,
303                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
304                                  errmsg("ON COMMIT can only be used on temporary tables")));
305
306         /*
307          * Look up the namespace in which we are supposed to create the relation.
308          * Check we have permission to create there. Skip check if bootstrapping,
309          * since permissions machinery may not be working yet.
310          */
311         namespaceId = RangeVarGetCreationNamespace(stmt->relation);
312
313         if (!IsBootstrapProcessingMode())
314         {
315                 AclResult       aclresult;
316
317                 aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
318                                                                                   ACL_CREATE);
319                 if (aclresult != ACLCHECK_OK)
320                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
321                                                    get_namespace_name(namespaceId));
322         }
323
324         /*
325          * Select tablespace to use.  If not specified, use default_tablespace
326          * (which may in turn default to database's default).
327          */
328         if (stmt->tablespacename)
329         {
330                 tablespaceId = get_tablespace_oid(stmt->tablespacename);
331                 if (!OidIsValid(tablespaceId))
332                         ereport(ERROR,
333                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
334                                          errmsg("tablespace \"%s\" does not exist",
335                                                         stmt->tablespacename)));
336         }
337         else
338         {
339                 tablespaceId = GetDefaultTablespace();
340                 /* note InvalidOid is OK in this case */
341         }
342
343         /*
344          * Parse and validate reloptions, if any.
345          */
346         reloptions = transformRelOptions((Datum) 0, stmt->options, true, false);
347
348         (void) heap_reloptions(relkind, reloptions, true);
349
350         /* Check permissions except when using database's default */
351         if (OidIsValid(tablespaceId))
352         {
353                 AclResult       aclresult;
354
355                 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
356                                                                                    ACL_CREATE);
357                 if (aclresult != ACLCHECK_OK)
358                         aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
359                                                    get_tablespace_name(tablespaceId));
360         }
361
362         /*
363          * Look up inheritance ancestors and generate relation schema, including
364          * inherited attributes.
365          */
366         schema = MergeAttributes(schema, stmt->inhRelations,
367                                                          stmt->relation->istemp,
368                                                          &inheritOids, &old_constraints, &parentOidCount);
369
370         /*
371          * Create a relation descriptor from the relation schema and create the
372          * relation.  Note that in this stage only inherited (pre-cooked) defaults
373          * and constraints will be included into the new relation.
374          * (BuildDescForRelation takes care of the inherited defaults, but we have
375          * to copy inherited constraints here.)
376          */
377         descriptor = BuildDescForRelation(schema);
378
379         localHasOids = interpretOidsOption(stmt->options);
380         descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
381
382         if (old_constraints || stmt->constraints)
383         {
384                 ConstrCheck *check;
385                 int                     ncheck = 0;
386
387                 /* make array that's certainly big enough */
388                 check = (ConstrCheck *)
389                         palloc((list_length(old_constraints) +
390                                         list_length(stmt->constraints)) * sizeof(ConstrCheck));
391                 /* deal with constraints from MergeAttributes */
392                 foreach(listptr, old_constraints)
393                 {
394                         Constraint *cdef = (Constraint *) lfirst(listptr);
395
396                         if (cdef->contype == CONSTR_CHECK)
397                                 add_nonduplicate_constraint(cdef, check, &ncheck);
398                 }
399                 /*
400                  * analyze.c might have passed some precooked constraints too,
401                  * due to LIKE tab INCLUDING CONSTRAINTS
402                  */
403                 foreach(listptr, stmt->constraints)
404                 {
405                         Constraint *cdef = (Constraint *) lfirst(listptr);
406
407                         if (cdef->contype == CONSTR_CHECK && cdef->cooked_expr != NULL)
408                                 add_nonduplicate_constraint(cdef, check, &ncheck);
409                 }
410                 /* if we found any, insert 'em into the descriptor */
411                 if (ncheck > 0)
412                 {
413                         if (descriptor->constr == NULL)
414                         {
415                                 descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
416                                 descriptor->constr->defval = NULL;
417                                 descriptor->constr->num_defval = 0;
418                                 descriptor->constr->has_not_null = false;
419                         }
420                         descriptor->constr->num_check = ncheck;
421                         descriptor->constr->check = check;
422                 }
423         }
424
425         relationId = heap_create_with_catalog(relname,
426                                                                                   namespaceId,
427                                                                                   tablespaceId,
428                                                                                   InvalidOid,
429                                                                                   GetUserId(),
430                                                                                   descriptor,
431                                                                                   relkind,
432                                                                                   false,
433                                                                                   localHasOids,
434                                                                                   parentOidCount,
435                                                                                   stmt->oncommit,
436                                                                                   reloptions,
437                                                                                   allowSystemTableMods);
438
439         StoreCatalogInheritance(relationId, inheritOids);
440
441         /*
442          * We must bump the command counter to make the newly-created relation
443          * tuple visible for opening.
444          */
445         CommandCounterIncrement();
446
447         /*
448          * Open the new relation and acquire exclusive lock on it.      This isn't
449          * really necessary for locking out other backends (since they can't see
450          * the new rel anyway until we commit), but it keeps the lock manager from
451          * complaining about deadlock risks.
452          */
453         rel = relation_open(relationId, AccessExclusiveLock);
454
455         /*
456          * Now add any newly specified column default values and CHECK constraints
457          * to the new relation.  These are passed to us in the form of raw
458          * parsetrees; we need to transform them to executable expression trees
459          * before they can be added. The most convenient way to do that is to
460          * apply the parser's transformExpr routine, but transformExpr doesn't
461          * work unless we have a pre-existing relation. So, the transformation has
462          * to be postponed to this final step of CREATE TABLE.
463          *
464          * First, scan schema to find new column defaults.
465          */
466         rawDefaults = NIL;
467         attnum = 0;
468
469         foreach(listptr, schema)
470         {
471                 ColumnDef  *colDef = lfirst(listptr);
472
473                 attnum++;
474
475                 if (colDef->raw_default != NULL)
476                 {
477                         RawColumnDefault *rawEnt;
478
479                         Assert(colDef->cooked_default == NULL);
480
481                         rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
482                         rawEnt->attnum = attnum;
483                         rawEnt->raw_default = colDef->raw_default;
484                         rawDefaults = lappend(rawDefaults, rawEnt);
485                 }
486         }
487
488         /*
489          * Parse and add the defaults/constraints, if any.
490          */
491         if (rawDefaults || stmt->constraints)
492                 AddRelationRawConstraints(rel, rawDefaults, stmt->constraints);
493
494         /*
495          * Clean up.  We keep lock on new relation (although it shouldn't be
496          * visible to anyone else anyway, until commit).
497          */
498         relation_close(rel, NoLock);
499
500         return relationId;
501 }
502
503 /*
504  * RemoveRelation
505  *              Deletes a relation.
506  */
507 void
508 RemoveRelation(const RangeVar *relation, DropBehavior behavior)
509 {
510         Oid                     relOid;
511         ObjectAddress object;
512
513         relOid = RangeVarGetRelid(relation, false);
514
515         object.classId = RelationRelationId;
516         object.objectId = relOid;
517         object.objectSubId = 0;
518
519         performDeletion(&object, behavior);
520 }
521
522 /*
523  * ExecuteTruncate
524  *              Executes a TRUNCATE command.
525  *
526  * This is a multi-relation truncate.  We first open and grab exclusive
527  * lock on all relations involved, checking permissions and otherwise
528  * verifying that the relation is OK for truncation.  In CASCADE mode,
529  * relations having FK references to the targeted relations are automatically
530  * added to the group; in RESTRICT mode, we check that all FK references are
531  * internal to the group that's being truncated.  Finally all the relations
532  * are truncated and reindexed.
533  */
534 void
535 ExecuteTruncate(TruncateStmt *stmt)
536 {
537         List       *rels = NIL;
538         List       *relids = NIL;
539         ListCell   *cell;
540
541         /*
542          * Open, exclusive-lock, and check all the explicitly-specified relations
543          */
544         foreach(cell, stmt->relations)
545         {
546                 RangeVar   *rv = lfirst(cell);
547                 Relation        rel;
548
549                 rel = heap_openrv(rv, AccessExclusiveLock);
550                 truncate_check_rel(rel);
551                 rels = lappend(rels, rel);
552                 relids = lappend_oid(relids, RelationGetRelid(rel));
553         }
554
555         /*
556          * In CASCADE mode, suck in all referencing relations as well.  This
557          * requires multiple iterations to find indirectly-dependent relations. At
558          * each phase, we need to exclusive-lock new rels before looking for their
559          * dependencies, else we might miss something.  Also, we check each rel as
560          * soon as we open it, to avoid a faux pas such as holding lock for a long
561          * time on a rel we have no permissions for.
562          */
563         if (stmt->behavior == DROP_CASCADE)
564         {
565                 for (;;)
566                 {
567                         List       *newrelids;
568
569                         newrelids = heap_truncate_find_FKs(relids);
570                         if (newrelids == NIL)
571                                 break;                  /* nothing else to add */
572
573                         foreach(cell, newrelids)
574                         {
575                                 Oid                     relid = lfirst_oid(cell);
576                                 Relation        rel;
577
578                                 rel = heap_open(relid, AccessExclusiveLock);
579                                 ereport(NOTICE,
580                                                 (errmsg("truncate cascades to table \"%s\"",
581                                                                 RelationGetRelationName(rel))));
582                                 truncate_check_rel(rel);
583                                 rels = lappend(rels, rel);
584                                 relids = lappend_oid(relids, relid);
585                         }
586                 }
587         }
588
589         /*
590          * Check foreign key references.  In CASCADE mode, this should be
591          * unnecessary since we just pulled in all the references; but as a
592          * cross-check, do it anyway if in an Assert-enabled build.
593          */
594 #ifdef USE_ASSERT_CHECKING
595         heap_truncate_check_FKs(rels, false);
596 #else
597         if (stmt->behavior == DROP_RESTRICT)
598                 heap_truncate_check_FKs(rels, false);
599 #endif
600
601         /*
602          * Also check for pending AFTER trigger events on the target relations. We
603          * can't just leave those be, since they will try to fetch tuples that the
604          * TRUNCATE removes.
605          */
606         AfterTriggerCheckTruncate(relids);
607
608         /*
609          * OK, truncate each table.
610          */
611         foreach(cell, rels)
612         {
613                 Relation        rel = (Relation) lfirst(cell);
614                 Oid                     heap_relid;
615                 Oid                     toast_relid;
616
617                 /*
618                  * Create a new empty storage file for the relation, and assign it as
619                  * the relfilenode value.       The old storage file is scheduled for
620                  * deletion at commit.
621                  */
622                 setNewRelfilenode(rel);
623
624                 heap_relid = RelationGetRelid(rel);
625                 toast_relid = rel->rd_rel->reltoastrelid;
626
627                 heap_close(rel, NoLock);
628
629                 /*
630                  * The same for the toast table, if any.
631                  */
632                 if (OidIsValid(toast_relid))
633                 {
634                         rel = relation_open(toast_relid, AccessExclusiveLock);
635                         setNewRelfilenode(rel);
636                         heap_close(rel, NoLock);
637                 }
638
639                 /*
640                  * Reconstruct the indexes to match, and we're done.
641                  */
642                 reindex_relation(heap_relid, true);
643         }
644 }
645
646 /*
647  * Check that a given rel is safe to truncate.  Subroutine for ExecuteTruncate
648  */
649 static void
650 truncate_check_rel(Relation rel)
651 {
652         /* Only allow truncate on regular tables */
653         if (rel->rd_rel->relkind != RELKIND_RELATION)
654                 ereport(ERROR,
655                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
656                                  errmsg("\"%s\" is not a table",
657                                                 RelationGetRelationName(rel))));
658
659         /* Permissions checks */
660         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
661                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
662                                            RelationGetRelationName(rel));
663
664         if (!allowSystemTableMods && IsSystemRelation(rel))
665                 ereport(ERROR,
666                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
667                                  errmsg("permission denied: \"%s\" is a system catalog",
668                                                 RelationGetRelationName(rel))));
669
670         /*
671          * We can never allow truncation of shared or nailed-in-cache relations,
672          * because we can't support changing their relfilenode values.
673          */
674         if (rel->rd_rel->relisshared || rel->rd_isnailed)
675                 ereport(ERROR,
676                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
677                                  errmsg("cannot truncate system relation \"%s\"",
678                                                 RelationGetRelationName(rel))));
679
680         /*
681          * Don't allow truncate on temp tables of other backends ... their local
682          * buffer manager is not going to cope.
683          */
684         if (isOtherTempNamespace(RelationGetNamespace(rel)))
685                 ereport(ERROR,
686                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
687                           errmsg("cannot truncate temporary tables of other sessions")));
688 }
689
690 /*----------
691  * MergeAttributes
692  *              Returns new schema given initial schema and superclasses.
693  *
694  * Input arguments:
695  * 'schema' is the column/attribute definition for the table. (It's a list
696  *              of ColumnDef's.) It is destructively changed.
697  * 'supers' is a list of names (as RangeVar nodes) of parent relations.
698  * 'istemp' is TRUE if we are creating a temp relation.
699  *
700  * Output arguments:
701  * 'supOids' receives a list of the OIDs of the parent relations.
702  * 'supconstr' receives a list of constraints belonging to the parents,
703  *              updated as necessary to be valid for the child.
704  * 'supOidCount' is set to the number of parents that have OID columns.
705  *
706  * Return value:
707  * Completed schema list.
708  *
709  * Notes:
710  *        The order in which the attributes are inherited is very important.
711  *        Intuitively, the inherited attributes should come first. If a table
712  *        inherits from multiple parents, the order of those attributes are
713  *        according to the order of the parents specified in CREATE TABLE.
714  *
715  *        Here's an example:
716  *
717  *              create table person (name text, age int4, location point);
718  *              create table emp (salary int4, manager text) inherits(person);
719  *              create table student (gpa float8) inherits (person);
720  *              create table stud_emp (percent int4) inherits (emp, student);
721  *
722  *        The order of the attributes of stud_emp is:
723  *
724  *                                                      person {1:name, 2:age, 3:location}
725  *                                                      /        \
726  *                         {6:gpa}      student   emp {4:salary, 5:manager}
727  *                                                      \        /
728  *                                                 stud_emp {7:percent}
729  *
730  *         If the same attribute name appears multiple times, then it appears
731  *         in the result table in the proper location for its first appearance.
732  *
733  *         Constraints (including NOT NULL constraints) for the child table
734  *         are the union of all relevant constraints, from both the child schema
735  *         and parent tables.
736  *
737  *         The default value for a child column is defined as:
738  *              (1) If the child schema specifies a default, that value is used.
739  *              (2) If neither the child nor any parent specifies a default, then
740  *                      the column will not have a default.
741  *              (3) If conflicting defaults are inherited from different parents
742  *                      (and not overridden by the child), an error is raised.
743  *              (4) Otherwise the inherited default is used.
744  *              Rule (3) is new in Postgres 7.1; in earlier releases you got a
745  *              rather arbitrary choice of which parent default to use.
746  *----------
747  */
748 static List *
749 MergeAttributes(List *schema, List *supers, bool istemp,
750                                 List **supOids, List **supconstr, int *supOidCount)
751 {
752         ListCell   *entry;
753         List       *inhSchema = NIL;
754         List       *parentOids = NIL;
755         List       *constraints = NIL;
756         int                     parentsWithOids = 0;
757         bool            have_bogus_defaults = false;
758         char       *bogus_marker = "Bogus!";            /* marks conflicting defaults */
759         int                     child_attno;
760
761         /*
762          * Check for and reject tables with too many columns. We perform this
763          * check relatively early for two reasons: (a) we don't run the risk of
764          * overflowing an AttrNumber in subsequent code (b) an O(n^2) algorithm is
765          * okay if we're processing <= 1600 columns, but could take minutes to
766          * execute if the user attempts to create a table with hundreds of
767          * thousands of columns.
768          *
769          * Note that we also need to check that any we do not exceed this figure
770          * after including columns from inherited relations.
771          */
772         if (list_length(schema) > MaxHeapAttributeNumber)
773                 ereport(ERROR,
774                                 (errcode(ERRCODE_TOO_MANY_COLUMNS),
775                                  errmsg("tables can have at most %d columns",
776                                                 MaxHeapAttributeNumber)));
777
778         /*
779          * Check for duplicate names in the explicit list of attributes.
780          *
781          * Although we might consider merging such entries in the same way that we
782          * handle name conflicts for inherited attributes, it seems to make more
783          * sense to assume such conflicts are errors.
784          */
785         foreach(entry, schema)
786         {
787                 ColumnDef  *coldef = lfirst(entry);
788                 ListCell   *rest;
789
790                 for_each_cell(rest, lnext(entry))
791                 {
792                         ColumnDef  *restdef = lfirst(rest);
793
794                         if (strcmp(coldef->colname, restdef->colname) == 0)
795                                 ereport(ERROR,
796                                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
797                                                  errmsg("column \"%s\" duplicated",
798                                                                 coldef->colname)));
799                 }
800         }
801
802         /*
803          * Scan the parents left-to-right, and merge their attributes to form a
804          * list of inherited attributes (inhSchema).  Also check to see if we need
805          * to inherit an OID column.
806          */
807         child_attno = 0;
808         foreach(entry, supers)
809         {
810                 RangeVar   *parent = (RangeVar *) lfirst(entry);
811                 Relation        relation;
812                 TupleDesc       tupleDesc;
813                 TupleConstr *constr;
814                 AttrNumber *newattno;
815                 AttrNumber      parent_attno;
816
817                 relation = heap_openrv(parent, AccessShareLock);
818
819                 if (relation->rd_rel->relkind != RELKIND_RELATION)
820                         ereport(ERROR,
821                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
822                                          errmsg("inherited relation \"%s\" is not a table",
823                                                         parent->relname)));
824                 /* Permanent rels cannot inherit from temporary ones */
825                 if (!istemp && isTempNamespace(RelationGetNamespace(relation)))
826                         ereport(ERROR,
827                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
828                                          errmsg("cannot inherit from temporary relation \"%s\"",
829                                                         parent->relname)));
830
831                 /*
832                  * We should have an UNDER permission flag for this, but for now,
833                  * demand that creator of a child table own the parent.
834                  */
835                 if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
836                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
837                                                    RelationGetRelationName(relation));
838
839                 /*
840                  * Reject duplications in the list of parents.
841                  */
842                 if (list_member_oid(parentOids, RelationGetRelid(relation)))
843                         ereport(ERROR,
844                                         (errcode(ERRCODE_DUPLICATE_TABLE),
845                                          errmsg("inherited relation \"%s\" duplicated",
846                                                         parent->relname)));
847
848                 parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
849
850                 if (relation->rd_rel->relhasoids)
851                         parentsWithOids++;
852
853                 tupleDesc = RelationGetDescr(relation);
854                 constr = tupleDesc->constr;
855
856                 /*
857                  * newattno[] will contain the child-table attribute numbers for the
858                  * attributes of this parent table.  (They are not the same for
859                  * parents after the first one, nor if we have dropped columns.)
860                  */
861                 newattno = (AttrNumber *)
862                         palloc(tupleDesc->natts * sizeof(AttrNumber));
863
864                 for (parent_attno = 1; parent_attno <= tupleDesc->natts;
865                          parent_attno++)
866                 {
867                         Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
868                         char       *attributeName = NameStr(attribute->attname);
869                         int                     exist_attno;
870                         ColumnDef  *def;
871
872                         /*
873                          * Ignore dropped columns in the parent.
874                          */
875                         if (attribute->attisdropped)
876                         {
877                                 /*
878                                  * change_varattnos_of_a_node asserts that this is greater
879                                  * than zero, so if anything tries to use it, we should find
880                                  * out.
881                                  */
882                                 newattno[parent_attno - 1] = 0;
883                                 continue;
884                         }
885
886                         /*
887                          * Does it conflict with some previously inherited column?
888                          */
889                         exist_attno = findAttrByName(attributeName, inhSchema);
890                         if (exist_attno > 0)
891                         {
892                                 /*
893                                  * Yes, try to merge the two column definitions. They must
894                                  * have the same type and typmod.
895                                  */
896                                 ereport(NOTICE,
897                                                 (errmsg("merging multiple inherited definitions of column \"%s\"",
898                                                                 attributeName)));
899                                 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
900                                 if (typenameTypeId(NULL, def->typename) != attribute->atttypid ||
901                                         def->typename->typmod != attribute->atttypmod)
902                                         ereport(ERROR,
903                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
904                                                 errmsg("inherited column \"%s\" has a type conflict",
905                                                            attributeName),
906                                                          errdetail("%s versus %s",
907                                                                            TypeNameToString(def->typename),
908                                                                            format_type_be(attribute->atttypid))));
909                                 def->inhcount++;
910                                 /* Merge of NOT NULL constraints = OR 'em together */
911                                 def->is_not_null |= attribute->attnotnull;
912                                 /* Default and other constraints are handled below */
913                                 newattno[parent_attno - 1] = exist_attno;
914                         }
915                         else
916                         {
917                                 /*
918                                  * No, create a new inherited column
919                                  */
920                                 def = makeNode(ColumnDef);
921                                 def->colname = pstrdup(attributeName);
922                                 def->typename = makeTypeNameFromOid(attribute->atttypid,
923                                                                                                         attribute->atttypmod);
924                                 def->inhcount = 1;
925                                 def->is_local = false;
926                                 def->is_not_null = attribute->attnotnull;
927                                 def->raw_default = NULL;
928                                 def->cooked_default = NULL;
929                                 def->constraints = NIL;
930                                 inhSchema = lappend(inhSchema, def);
931                                 newattno[parent_attno - 1] = ++child_attno;
932                         }
933
934                         /*
935                          * Copy default if any
936                          */
937                         if (attribute->atthasdef)
938                         {
939                                 char       *this_default = NULL;
940                                 AttrDefault *attrdef;
941                                 int                     i;
942
943                                 /* Find default in constraint structure */
944                                 Assert(constr != NULL);
945                                 attrdef = constr->defval;
946                                 for (i = 0; i < constr->num_defval; i++)
947                                 {
948                                         if (attrdef[i].adnum == parent_attno)
949                                         {
950                                                 this_default = attrdef[i].adbin;
951                                                 break;
952                                         }
953                                 }
954                                 Assert(this_default != NULL);
955
956                                 /*
957                                  * If default expr could contain any vars, we'd need to fix
958                                  * 'em, but it can't; so default is ready to apply to child.
959                                  *
960                                  * If we already had a default from some prior parent, check
961                                  * to see if they are the same.  If so, no problem; if not,
962                                  * mark the column as having a bogus default. Below, we will
963                                  * complain if the bogus default isn't overridden by the child
964                                  * schema.
965                                  */
966                                 Assert(def->raw_default == NULL);
967                                 if (def->cooked_default == NULL)
968                                         def->cooked_default = pstrdup(this_default);
969                                 else if (strcmp(def->cooked_default, this_default) != 0)
970                                 {
971                                         def->cooked_default = bogus_marker;
972                                         have_bogus_defaults = true;
973                                 }
974                         }
975                 }
976
977                 /*
978                  * Now copy the constraints of this parent, adjusting attnos using the
979                  * completed newattno[] map
980                  */
981                 if (constr && constr->num_check > 0)
982                 {
983                         ConstrCheck *check = constr->check;
984                         int                     i;
985
986                         for (i = 0; i < constr->num_check; i++)
987                         {
988                                 Constraint *cdef = makeNode(Constraint);
989                                 Node       *expr;
990
991                                 cdef->contype = CONSTR_CHECK;
992                                 cdef->name = pstrdup(check[i].ccname);
993                                 cdef->raw_expr = NULL;
994                                 /* adjust varattnos of ccbin here */
995                                 expr = stringToNode(check[i].ccbin);
996                                 change_varattnos_of_a_node(expr, newattno);
997                                 cdef->cooked_expr = nodeToString(expr);
998                                 constraints = lappend(constraints, cdef);
999                         }
1000                 }
1001
1002                 pfree(newattno);
1003
1004                 /*
1005                  * Close the parent rel, but keep our AccessShareLock on it until xact
1006                  * commit.      That will prevent someone else from deleting or ALTERing
1007                  * the parent before the child is committed.
1008                  */
1009                 heap_close(relation, NoLock);
1010         }
1011
1012         /*
1013          * If we had no inherited attributes, the result schema is just the
1014          * explicitly declared columns.  Otherwise, we need to merge the declared
1015          * columns into the inherited schema list.
1016          */
1017         if (inhSchema != NIL)
1018         {
1019                 foreach(entry, schema)
1020                 {
1021                         ColumnDef  *newdef = lfirst(entry);
1022                         char       *attributeName = newdef->colname;
1023                         int                     exist_attno;
1024
1025                         /*
1026                          * Does it conflict with some previously inherited column?
1027                          */
1028                         exist_attno = findAttrByName(attributeName, inhSchema);
1029                         if (exist_attno > 0)
1030                         {
1031                                 ColumnDef  *def;
1032
1033                                 /*
1034                                  * Yes, try to merge the two column definitions. They must
1035                                  * have the same type and typmod.
1036                                  */
1037                                 ereport(NOTICE,
1038                                    (errmsg("merging column \"%s\" with inherited definition",
1039                                                    attributeName)));
1040                                 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1041                                 if (typenameTypeId(NULL, def->typename) != typenameTypeId(NULL, newdef->typename) ||
1042                                         def->typename->typmod != newdef->typename->typmod)
1043                                         ereport(ERROR,
1044                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1045                                                          errmsg("column \"%s\" has a type conflict",
1046                                                                         attributeName),
1047                                                          errdetail("%s versus %s",
1048                                                                            TypeNameToString(def->typename),
1049                                                                            TypeNameToString(newdef->typename))));
1050                                 /* Mark the column as locally defined */
1051                                 def->is_local = true;
1052                                 /* Merge of NOT NULL constraints = OR 'em together */
1053                                 def->is_not_null |= newdef->is_not_null;
1054                                 /* If new def has a default, override previous default */
1055                                 if (newdef->raw_default != NULL)
1056                                 {
1057                                         def->raw_default = newdef->raw_default;
1058                                         def->cooked_default = newdef->cooked_default;
1059                                 }
1060                         }
1061                         else
1062                         {
1063                                 /*
1064                                  * No, attach new column to result schema
1065                                  */
1066                                 inhSchema = lappend(inhSchema, newdef);
1067                         }
1068                 }
1069
1070                 schema = inhSchema;
1071
1072                 /*
1073                  * Check that we haven't exceeded the legal # of columns after merging
1074                  * in inherited columns.
1075                  */
1076                 if (list_length(schema) > MaxHeapAttributeNumber)
1077                         ereport(ERROR,
1078                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
1079                                          errmsg("tables can have at most %d columns",
1080                                                         MaxHeapAttributeNumber)));
1081         }
1082
1083         /*
1084          * If we found any conflicting parent default values, check to make sure
1085          * they were overridden by the child.
1086          */
1087         if (have_bogus_defaults)
1088         {
1089                 foreach(entry, schema)
1090                 {
1091                         ColumnDef  *def = lfirst(entry);
1092
1093                         if (def->cooked_default == bogus_marker)
1094                                 ereport(ERROR,
1095                                                 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
1096                                   errmsg("column \"%s\" inherits conflicting default values",
1097                                                  def->colname),
1098                                                  errhint("To resolve the conflict, specify a default explicitly.")));
1099                 }
1100         }
1101
1102         *supOids = parentOids;
1103         *supconstr = constraints;
1104         *supOidCount = parentsWithOids;
1105         return schema;
1106 }
1107
1108
1109 /*
1110  * In multiple-inheritance situations, it's possible to inherit
1111  * the same grandparent constraint through multiple parents.
1112  * Hence, we want to discard inherited constraints that match as to
1113  * both name and expression.  Otherwise, gripe if there are conflicting
1114  * names.  Nonconflicting constraints are added to the array check[]
1115  * of length *ncheck ... caller must ensure there is room!
1116  */
1117 static void
1118 add_nonduplicate_constraint(Constraint *cdef, ConstrCheck *check, int *ncheck)
1119 {
1120         int                     i;
1121
1122         /* Should only see precooked constraints here */
1123         Assert(cdef->contype == CONSTR_CHECK);
1124         Assert(cdef->name != NULL);
1125         Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL);
1126
1127         for (i = 0; i < *ncheck; i++)
1128         {
1129                 if (strcmp(check[i].ccname, cdef->name) != 0)
1130                         continue;
1131                 if (strcmp(check[i].ccbin, cdef->cooked_expr) == 0)
1132                         return;                         /* duplicate constraint, so ignore it */
1133                 ereport(ERROR,
1134                                 (errcode(ERRCODE_DUPLICATE_OBJECT),
1135                                  errmsg("duplicate check constraint name \"%s\"",
1136                                                 cdef->name)));
1137         }
1138         /* No match on name, so add it to array */
1139         check[*ncheck].ccname = cdef->name;
1140         check[*ncheck].ccbin = pstrdup(cdef->cooked_expr);
1141         (*ncheck)++;
1142 }
1143
1144
1145 /*
1146  * Replace varattno values in an expression tree according to the given
1147  * map array, that is, varattno N is replaced by newattno[N-1].  It is
1148  * caller's responsibility to ensure that the array is long enough to
1149  * define values for all user varattnos present in the tree.  System column
1150  * attnos remain unchanged.
1151  *
1152  * Note that the passed node tree is modified in-place!
1153  */
1154 void
1155 change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1156 {
1157         /* no setup needed, so away we go */
1158         (void) change_varattnos_walker(node, newattno);
1159 }
1160
1161 static bool
1162 change_varattnos_walker(Node *node, const AttrNumber *newattno)
1163 {
1164         if (node == NULL)
1165                 return false;
1166         if (IsA(node, Var))
1167         {
1168                 Var                *var = (Var *) node;
1169
1170                 if (var->varlevelsup == 0 && var->varno == 1 &&
1171                         var->varattno > 0)
1172                 {
1173                         /*
1174                          * ??? the following may be a problem when the node is multiply
1175                          * referenced though stringToNode() doesn't create such a node
1176                          * currently.
1177                          */
1178                         Assert(newattno[var->varattno - 1] > 0);
1179                         var->varattno = newattno[var->varattno - 1];
1180                 }
1181                 return false;
1182         }
1183         return expression_tree_walker(node, change_varattnos_walker,
1184                                                                   (void *) newattno);
1185 }
1186
1187 /*
1188  * Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
1189  * matching according to column name.
1190  */
1191 AttrNumber *
1192 varattnos_map(TupleDesc old, TupleDesc new)
1193 {
1194         AttrNumber *attmap;
1195         int                     i,
1196                                 j;
1197
1198         attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
1199         for (i = 1; i <= old->natts; i++)
1200         {
1201                 if (old->attrs[i - 1]->attisdropped)
1202                         continue;                       /* leave the entry as zero */
1203
1204                 for (j = 1; j <= new->natts; j++)
1205                 {
1206                         if (strcmp(NameStr(old->attrs[i - 1]->attname),
1207                                            NameStr(new->attrs[j - 1]->attname)) == 0)
1208                         {
1209                                 attmap[i - 1] = j;
1210                                 break;
1211                         }
1212                 }
1213         }
1214         return attmap;
1215 }
1216
1217 /*
1218  * Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
1219  * of ColumnDefs
1220  */
1221 AttrNumber *
1222 varattnos_map_schema(TupleDesc old, List *schema)
1223 {
1224         AttrNumber *attmap;
1225         int                     i;
1226
1227         attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
1228         for (i = 1; i <= old->natts; i++)
1229         {
1230                 if (old->attrs[i - 1]->attisdropped)
1231                         continue;                       /* leave the entry as zero */
1232
1233                 attmap[i - 1] = findAttrByName(NameStr(old->attrs[i - 1]->attname),
1234                                                                            schema);
1235         }
1236         return attmap;
1237 }
1238
1239
1240 /*
1241  * StoreCatalogInheritance
1242  *              Updates the system catalogs with proper inheritance information.
1243  *
1244  * supers is a list of the OIDs of the new relation's direct ancestors.
1245  */
1246 static void
1247 StoreCatalogInheritance(Oid relationId, List *supers)
1248 {
1249         Relation        relation;
1250         int16           seqNumber;
1251         ListCell   *entry;
1252
1253         /*
1254          * sanity checks
1255          */
1256         AssertArg(OidIsValid(relationId));
1257
1258         if (supers == NIL)
1259                 return;
1260
1261         /*
1262          * Store INHERITS information in pg_inherits using direct ancestors only.
1263          * Also enter dependencies on the direct ancestors, and make sure they are
1264          * marked with relhassubclass = true.
1265          *
1266          * (Once upon a time, both direct and indirect ancestors were found here
1267          * and then entered into pg_ipl.  Since that catalog doesn't exist
1268          * anymore, there's no need to look for indirect ancestors.)
1269          */
1270         relation = heap_open(InheritsRelationId, RowExclusiveLock);
1271
1272         seqNumber = 1;
1273         foreach(entry, supers)
1274         {
1275                 Oid                     parentOid = lfirst_oid(entry);
1276
1277                 StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation);
1278                 seqNumber++;
1279         }
1280
1281         heap_close(relation, RowExclusiveLock);
1282 }
1283
1284 /*
1285  * Make catalog entries showing relationId as being an inheritance child
1286  * of parentOid.  inhRelation is the already-opened pg_inherits catalog.
1287  */
1288 static void
1289 StoreCatalogInheritance1(Oid relationId, Oid parentOid,
1290                                                  int16 seqNumber, Relation inhRelation)
1291 {
1292         TupleDesc       desc = RelationGetDescr(inhRelation);
1293         Datum           datum[Natts_pg_inherits];
1294         char            nullarr[Natts_pg_inherits];
1295         ObjectAddress childobject,
1296                                 parentobject;
1297         HeapTuple       tuple;
1298
1299         /*
1300          * Make the pg_inherits entry
1301          */
1302         datum[0] = ObjectIdGetDatum(relationId);        /* inhrelid */
1303         datum[1] = ObjectIdGetDatum(parentOid);         /* inhparent */
1304         datum[2] = Int16GetDatum(seqNumber);            /* inhseqno */
1305
1306         nullarr[0] = ' ';
1307         nullarr[1] = ' ';
1308         nullarr[2] = ' ';
1309
1310         tuple = heap_formtuple(desc, datum, nullarr);
1311
1312         simple_heap_insert(inhRelation, tuple);
1313
1314         CatalogUpdateIndexes(inhRelation, tuple);
1315
1316         heap_freetuple(tuple);
1317
1318         /*
1319          * Store a dependency too
1320          */
1321         parentobject.classId = RelationRelationId;
1322         parentobject.objectId = parentOid;
1323         parentobject.objectSubId = 0;
1324         childobject.classId = RelationRelationId;
1325         childobject.objectId = relationId;
1326         childobject.objectSubId = 0;
1327
1328         recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
1329
1330         /*
1331          * Mark the parent as having subclasses.
1332          */
1333         setRelhassubclassInRelation(parentOid, true);
1334 }
1335
1336 /*
1337  * Look for an existing schema entry with the given name.
1338  *
1339  * Returns the index (starting with 1) if attribute already exists in schema,
1340  * 0 if it doesn't.
1341  */
1342 static int
1343 findAttrByName(const char *attributeName, List *schema)
1344 {
1345         ListCell   *s;
1346         int                     i = 1;
1347
1348         foreach(s, schema)
1349         {
1350                 ColumnDef  *def = lfirst(s);
1351
1352                 if (strcmp(attributeName, def->colname) == 0)
1353                         return i;
1354
1355                 i++;
1356         }
1357         return 0;
1358 }
1359
1360 /*
1361  * Update a relation's pg_class.relhassubclass entry to the given value
1362  */
1363 static void
1364 setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1365 {
1366         Relation        relationRelation;
1367         HeapTuple       tuple;
1368         Form_pg_class classtuple;
1369
1370         /*
1371          * Fetch a modifiable copy of the tuple, modify it, update pg_class.
1372          *
1373          * If the tuple already has the right relhassubclass setting, we don't
1374          * need to update it, but we still need to issue an SI inval message.
1375          */
1376         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
1377         tuple = SearchSysCacheCopy(RELOID,
1378                                                            ObjectIdGetDatum(relationId),
1379                                                            0, 0, 0);
1380         if (!HeapTupleIsValid(tuple))
1381                 elog(ERROR, "cache lookup failed for relation %u", relationId);
1382         classtuple = (Form_pg_class) GETSTRUCT(tuple);
1383
1384         if (classtuple->relhassubclass != relhassubclass)
1385         {
1386                 classtuple->relhassubclass = relhassubclass;
1387                 simple_heap_update(relationRelation, &tuple->t_self, tuple);
1388
1389                 /* keep the catalog indexes up to date */
1390                 CatalogUpdateIndexes(relationRelation, tuple);
1391         }
1392         else
1393         {
1394                 /* no need to change tuple, but force relcache rebuild anyway */
1395                 CacheInvalidateRelcacheByTuple(tuple);
1396         }
1397
1398         heap_freetuple(tuple);
1399         heap_close(relationRelation, RowExclusiveLock);
1400 }
1401
1402
1403 /*
1404  *              renameatt               - changes the name of a attribute in a relation
1405  *
1406  *              Attname attribute is changed in attribute catalog.
1407  *              No record of the previous attname is kept (correct?).
1408  *
1409  *              get proper relrelation from relation catalog (if not arg)
1410  *              scan attribute catalog
1411  *                              for name conflict (within rel)
1412  *                              for original attribute (if not arg)
1413  *              modify attname in attribute tuple
1414  *              insert modified attribute in attribute catalog
1415  *              delete original attribute from attribute catalog
1416  */
1417 void
1418 renameatt(Oid myrelid,
1419                   const char *oldattname,
1420                   const char *newattname,
1421                   bool recurse,
1422                   bool recursing)
1423 {
1424         Relation        targetrelation;
1425         Relation        attrelation;
1426         HeapTuple       atttup;
1427         Form_pg_attribute attform;
1428         int                     attnum;
1429         List       *indexoidlist;
1430         ListCell   *indexoidscan;
1431
1432         /*
1433          * Grab an exclusive lock on the target table, which we will NOT release
1434          * until end of transaction.
1435          */
1436         targetrelation = relation_open(myrelid, AccessExclusiveLock);
1437
1438         /*
1439          * permissions checking.  this would normally be done in utility.c, but
1440          * this particular routine is recursive.
1441          *
1442          * normally, only the owner of a class can change its schema.
1443          */
1444         if (!pg_class_ownercheck(myrelid, GetUserId()))
1445                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
1446                                            RelationGetRelationName(targetrelation));
1447         if (!allowSystemTableMods && IsSystemRelation(targetrelation))
1448                 ereport(ERROR,
1449                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1450                                  errmsg("permission denied: \"%s\" is a system catalog",
1451                                                 RelationGetRelationName(targetrelation))));
1452
1453         /*
1454          * if the 'recurse' flag is set then we are supposed to rename this
1455          * attribute in all classes that inherit from 'relname' (as well as in
1456          * 'relname').
1457          *
1458          * any permissions or problems with duplicate attributes will cause the
1459          * whole transaction to abort, which is what we want -- all or nothing.
1460          */
1461         if (recurse)
1462         {
1463                 ListCell   *child;
1464                 List       *children;
1465
1466                 /* this routine is actually in the planner */
1467                 children = find_all_inheritors(myrelid);
1468
1469                 /*
1470                  * find_all_inheritors does the recursive search of the inheritance
1471                  * hierarchy, so all we have to do is process all of the relids in the
1472                  * list that it returns.
1473                  */
1474                 foreach(child, children)
1475                 {
1476                         Oid                     childrelid = lfirst_oid(child);
1477
1478                         if (childrelid == myrelid)
1479                                 continue;
1480                         /* note we need not recurse again */
1481                         renameatt(childrelid, oldattname, newattname, false, true);
1482                 }
1483         }
1484         else
1485         {
1486                 /*
1487                  * If we are told not to recurse, there had better not be any child
1488                  * tables; else the rename would put them out of step.
1489                  */
1490                 if (!recursing &&
1491                         find_inheritance_children(myrelid) != NIL)
1492                         ereport(ERROR,
1493                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1494                                          errmsg("inherited column \"%s\" must be renamed in child tables too",
1495                                                         oldattname)));
1496         }
1497
1498         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
1499
1500         atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
1501         if (!HeapTupleIsValid(atttup))
1502                 ereport(ERROR,
1503                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
1504                                  errmsg("column \"%s\" does not exist",
1505                                                 oldattname)));
1506         attform = (Form_pg_attribute) GETSTRUCT(atttup);
1507
1508         attnum = attform->attnum;
1509         if (attnum <= 0)
1510                 ereport(ERROR,
1511                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1512                                  errmsg("cannot rename system column \"%s\"",
1513                                                 oldattname)));
1514
1515         /*
1516          * if the attribute is inherited, forbid the renaming, unless we are
1517          * already inside a recursive rename.
1518          */
1519         if (attform->attinhcount > 0 && !recursing)
1520                 ereport(ERROR,
1521                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1522                                  errmsg("cannot rename inherited column \"%s\"",
1523                                                 oldattname)));
1524
1525         /* should not already exist */
1526         /* this test is deliberately not attisdropped-aware */
1527         if (SearchSysCacheExists(ATTNAME,
1528                                                          ObjectIdGetDatum(myrelid),
1529                                                          PointerGetDatum(newattname),
1530                                                          0, 0))
1531                 ereport(ERROR,
1532                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
1533                                  errmsg("column \"%s\" of relation \"%s\" already exists",
1534                                           newattname, RelationGetRelationName(targetrelation))));
1535
1536         namestrcpy(&(attform->attname), newattname);
1537
1538         simple_heap_update(attrelation, &atttup->t_self, atttup);
1539
1540         /* keep system catalog indexes current */
1541         CatalogUpdateIndexes(attrelation, atttup);
1542
1543         heap_freetuple(atttup);
1544
1545         /*
1546          * Update column names of indexes that refer to the column being renamed.
1547          */
1548         indexoidlist = RelationGetIndexList(targetrelation);
1549
1550         foreach(indexoidscan, indexoidlist)
1551         {
1552                 Oid                     indexoid = lfirst_oid(indexoidscan);
1553                 HeapTuple       indextup;
1554                 Form_pg_index indexform;
1555                 int                     i;
1556
1557                 /*
1558                  * Scan through index columns to see if there's any simple index
1559                  * entries for this attribute.  We ignore expressional entries.
1560                  */
1561                 indextup = SearchSysCache(INDEXRELID,
1562                                                                   ObjectIdGetDatum(indexoid),
1563                                                                   0, 0, 0);
1564                 if (!HeapTupleIsValid(indextup))
1565                         elog(ERROR, "cache lookup failed for index %u", indexoid);
1566                 indexform = (Form_pg_index) GETSTRUCT(indextup);
1567
1568                 for (i = 0; i < indexform->indnatts; i++)
1569                 {
1570                         if (attnum != indexform->indkey.values[i])
1571                                 continue;
1572
1573                         /*
1574                          * Found one, rename it.
1575                          */
1576                         atttup = SearchSysCacheCopy(ATTNUM,
1577                                                                                 ObjectIdGetDatum(indexoid),
1578                                                                                 Int16GetDatum(i + 1),
1579                                                                                 0, 0);
1580                         if (!HeapTupleIsValid(atttup))
1581                                 continue;               /* should we raise an error? */
1582
1583                         /*
1584                          * Update the (copied) attribute tuple.
1585                          */
1586                         namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
1587                                            newattname);
1588
1589                         simple_heap_update(attrelation, &atttup->t_self, atttup);
1590
1591                         /* keep system catalog indexes current */
1592                         CatalogUpdateIndexes(attrelation, atttup);
1593
1594                         heap_freetuple(atttup);
1595                 }
1596
1597                 ReleaseSysCache(indextup);
1598         }
1599
1600         list_free(indexoidlist);
1601
1602         heap_close(attrelation, RowExclusiveLock);
1603
1604         /*
1605          * Update att name in any RI triggers associated with the relation.
1606          */
1607         if (targetrelation->rd_rel->reltriggers > 0)
1608         {
1609                 /* update tgargs column reference where att is primary key */
1610                 update_ri_trigger_args(RelationGetRelid(targetrelation),
1611                                                            oldattname, newattname,
1612                                                            false, false);
1613                 /* update tgargs column reference where att is foreign key */
1614                 update_ri_trigger_args(RelationGetRelid(targetrelation),
1615                                                            oldattname, newattname,
1616                                                            true, false);
1617         }
1618
1619         relation_close(targetrelation, NoLock);         /* close rel but keep lock */
1620 }
1621
1622 /*
1623  *              renamerel               - change the name of a relation
1624  *
1625  *              XXX - When renaming sequences, we don't bother to modify the
1626  *                        sequence name that is stored within the sequence itself
1627  *                        (this would cause problems with MVCC). In the future,
1628  *                        the sequence name should probably be removed from the
1629  *                        sequence, AFAIK there's no need for it to be there.
1630  */
1631 void
1632 renamerel(Oid myrelid, const char *newrelname)
1633 {
1634         Relation        targetrelation;
1635         Relation        relrelation;    /* for RELATION relation */
1636         HeapTuple       reltup;
1637         Oid                     namespaceId;
1638         char       *oldrelname;
1639         char            relkind;
1640         bool            relhastriggers;
1641
1642         /*
1643          * Grab an exclusive lock on the target table or index, which we will NOT
1644          * release until end of transaction.
1645          */
1646         targetrelation = relation_open(myrelid, AccessExclusiveLock);
1647
1648         oldrelname = pstrdup(RelationGetRelationName(targetrelation));
1649         namespaceId = RelationGetNamespace(targetrelation);
1650
1651         if (!allowSystemTableMods && IsSystemRelation(targetrelation))
1652                 ereport(ERROR,
1653                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1654                                  errmsg("permission denied: \"%s\" is a system catalog",
1655                                                 RelationGetRelationName(targetrelation))));
1656
1657         relkind = targetrelation->rd_rel->relkind;
1658         relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
1659
1660         /*
1661          * Find relation's pg_class tuple, and make sure newrelname isn't in use.
1662          */
1663         relrelation = heap_open(RelationRelationId, RowExclusiveLock);
1664
1665         reltup = SearchSysCacheCopy(RELOID,
1666                                                                 PointerGetDatum(myrelid),
1667                                                                 0, 0, 0);
1668         if (!HeapTupleIsValid(reltup))          /* shouldn't happen */
1669                 elog(ERROR, "cache lookup failed for relation %u", myrelid);
1670
1671         if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
1672                 ereport(ERROR,
1673                                 (errcode(ERRCODE_DUPLICATE_TABLE),
1674                                  errmsg("relation \"%s\" already exists",
1675                                                 newrelname)));
1676
1677         /*
1678          * Update pg_class tuple with new relname.      (Scribbling on reltup is OK
1679          * because it's a copy...)
1680          */
1681         namestrcpy(&(((Form_pg_class) GETSTRUCT(reltup))->relname), newrelname);
1682
1683         simple_heap_update(relrelation, &reltup->t_self, reltup);
1684
1685         /* keep the system catalog indexes current */
1686         CatalogUpdateIndexes(relrelation, reltup);
1687
1688         heap_freetuple(reltup);
1689         heap_close(relrelation, RowExclusiveLock);
1690
1691         /*
1692          * Also rename the associated type, if any.
1693          */
1694         if (relkind != RELKIND_INDEX)
1695                 TypeRename(oldrelname, namespaceId, newrelname);
1696
1697         /*
1698          * Update rel name in any RI triggers associated with the relation.
1699          */
1700         if (relhastriggers)
1701         {
1702                 /* update tgargs where relname is primary key */
1703                 update_ri_trigger_args(myrelid,
1704                                                            oldrelname,
1705                                                            newrelname,
1706                                                            false, true);
1707                 /* update tgargs where relname is foreign key */
1708                 update_ri_trigger_args(myrelid,
1709                                                            oldrelname,
1710                                                            newrelname,
1711                                                            true, true);
1712         }
1713
1714         /*
1715          * Close rel, but keep exclusive lock!
1716          */
1717         relation_close(targetrelation, NoLock);
1718 }
1719
1720 /*
1721  * Scan pg_trigger for RI triggers that are on the specified relation
1722  * (if fk_scan is false) or have it as the tgconstrrel (if fk_scan
1723  * is true).  Update RI trigger args fields matching oldname to contain
1724  * newname instead.  If update_relname is true, examine the relname
1725  * fields; otherwise examine the attname fields.
1726  */
1727 static void
1728 update_ri_trigger_args(Oid relid,
1729                                            const char *oldname,
1730                                            const char *newname,
1731                                            bool fk_scan,
1732                                            bool update_relname)
1733 {
1734         Relation        tgrel;
1735         ScanKeyData skey[1];
1736         SysScanDesc trigscan;
1737         HeapTuple       tuple;
1738         Datum           values[Natts_pg_trigger];
1739         char            nulls[Natts_pg_trigger];
1740         char            replaces[Natts_pg_trigger];
1741
1742         tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
1743         if (fk_scan)
1744         {
1745                 ScanKeyInit(&skey[0],
1746                                         Anum_pg_trigger_tgconstrrelid,
1747                                         BTEqualStrategyNumber, F_OIDEQ,
1748                                         ObjectIdGetDatum(relid));
1749                 trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndexId,
1750                                                                           true, SnapshotNow,
1751                                                                           1, skey);
1752         }
1753         else
1754         {
1755                 ScanKeyInit(&skey[0],
1756                                         Anum_pg_trigger_tgrelid,
1757                                         BTEqualStrategyNumber, F_OIDEQ,
1758                                         ObjectIdGetDatum(relid));
1759                 trigscan = systable_beginscan(tgrel, TriggerRelidNameIndexId,
1760                                                                           true, SnapshotNow,
1761                                                                           1, skey);
1762         }
1763
1764         while ((tuple = systable_getnext(trigscan)) != NULL)
1765         {
1766                 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
1767                 bytea      *val;
1768                 bytea      *newtgargs;
1769                 bool            isnull;
1770                 int                     tg_type;
1771                 bool            examine_pk;
1772                 bool            changed;
1773                 int                     tgnargs;
1774                 int                     i;
1775                 int                     newlen;
1776                 const char *arga[RI_MAX_ARGUMENTS];
1777                 const char *argp;
1778
1779                 tg_type = RI_FKey_trigger_type(pg_trigger->tgfoid);
1780                 if (tg_type == RI_TRIGGER_NONE)
1781                 {
1782                         /* Not an RI trigger, forget it */
1783                         continue;
1784                 }
1785
1786                 /*
1787                  * It is an RI trigger, so parse the tgargs bytea.
1788                  *
1789                  * NB: we assume the field will never be compressed or moved out of
1790                  * line; so does trigger.c ...
1791                  */
1792                 tgnargs = pg_trigger->tgnargs;
1793                 val = (bytea *)
1794                         DatumGetPointer(fastgetattr(tuple,
1795                                                                                 Anum_pg_trigger_tgargs,
1796                                                                                 tgrel->rd_att, &isnull));
1797                 if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
1798                         tgnargs > RI_MAX_ARGUMENTS)
1799                 {
1800                         /* This probably shouldn't happen, but ignore busted triggers */
1801                         continue;
1802                 }
1803                 argp = (const char *) VARDATA(val);
1804                 for (i = 0; i < tgnargs; i++)
1805                 {
1806                         arga[i] = argp;
1807                         argp += strlen(argp) + 1;
1808                 }
1809
1810                 /*
1811                  * Figure out which item(s) to look at.  If the trigger is primary-key
1812                  * type and attached to my rel, I should look at the PK fields; if it
1813                  * is foreign-key type and attached to my rel, I should look at the FK
1814                  * fields.      But the opposite rule holds when examining triggers found
1815                  * by tgconstrrel search.
1816                  */
1817                 examine_pk = (tg_type == RI_TRIGGER_PK) == (!fk_scan);
1818
1819                 changed = false;
1820                 if (update_relname)
1821                 {
1822                         /* Change the relname if needed */
1823                         i = examine_pk ? RI_PK_RELNAME_ARGNO : RI_FK_RELNAME_ARGNO;
1824                         if (strcmp(arga[i], oldname) == 0)
1825                         {
1826                                 arga[i] = newname;
1827                                 changed = true;
1828                         }
1829                 }
1830                 else
1831                 {
1832                         /* Change attname(s) if needed */
1833                         i = examine_pk ? RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_PK_IDX :
1834                                 RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_FK_IDX;
1835                         for (; i < tgnargs; i += 2)
1836                         {
1837                                 if (strcmp(arga[i], oldname) == 0)
1838                                 {
1839                                         arga[i] = newname;
1840                                         changed = true;
1841                                 }
1842                         }
1843                 }
1844
1845                 if (!changed)
1846                 {
1847                         /* Don't need to update this tuple */
1848                         continue;
1849                 }
1850
1851                 /*
1852                  * Construct modified tgargs bytea.
1853                  */
1854                 newlen = VARHDRSZ;
1855                 for (i = 0; i < tgnargs; i++)
1856                         newlen += strlen(arga[i]) + 1;
1857                 newtgargs = (bytea *) palloc(newlen);
1858                 VARATT_SIZEP(newtgargs) = newlen;
1859                 newlen = VARHDRSZ;
1860                 for (i = 0; i < tgnargs; i++)
1861                 {
1862                         strcpy(((char *) newtgargs) + newlen, arga[i]);
1863                         newlen += strlen(arga[i]) + 1;
1864                 }
1865
1866                 /*
1867                  * Build modified tuple.
1868                  */
1869                 for (i = 0; i < Natts_pg_trigger; i++)
1870                 {
1871                         values[i] = (Datum) 0;
1872                         replaces[i] = ' ';
1873                         nulls[i] = ' ';
1874                 }
1875                 values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(newtgargs);
1876                 replaces[Anum_pg_trigger_tgargs - 1] = 'r';
1877
1878                 tuple = heap_modifytuple(tuple, RelationGetDescr(tgrel), values, nulls, replaces);
1879
1880                 /*
1881                  * Update pg_trigger and its indexes
1882                  */
1883                 simple_heap_update(tgrel, &tuple->t_self, tuple);
1884
1885                 CatalogUpdateIndexes(tgrel, tuple);
1886
1887                 /*
1888                  * Invalidate trigger's relation's relcache entry so that other
1889                  * backends (and this one too!) are sent SI message to make them
1890                  * rebuild relcache entries.  (Ideally this should happen
1891                  * automatically...)
1892                  *
1893                  * We can skip this for triggers on relid itself, since that relcache
1894                  * flush will happen anyway due to the table or column rename.  We
1895                  * just need to catch the far ends of RI relationships.
1896                  */
1897                 pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
1898                 if (pg_trigger->tgrelid != relid)
1899                         CacheInvalidateRelcacheByRelid(pg_trigger->tgrelid);
1900
1901                 /* free up our scratch memory */
1902                 pfree(newtgargs);
1903                 heap_freetuple(tuple);
1904         }
1905
1906         systable_endscan(trigscan);
1907
1908         heap_close(tgrel, RowExclusiveLock);
1909
1910         /*
1911          * Increment cmd counter to make updates visible; this is needed in case
1912          * the same tuple has to be updated again by next pass (can happen in case
1913          * of a self-referential FK relationship).
1914          */
1915         CommandCounterIncrement();
1916 }
1917
1918 /*
1919  * AlterTable
1920  *              Execute ALTER TABLE, which can be a list of subcommands
1921  *
1922  * ALTER TABLE is performed in three phases:
1923  *              1. Examine subcommands and perform pre-transformation checking.
1924  *              2. Update system catalogs.
1925  *              3. Scan table(s) to check new constraints, and optionally recopy
1926  *                 the data into new table(s).
1927  * Phase 3 is not performed unless one or more of the subcommands requires
1928  * it.  The intention of this design is to allow multiple independent
1929  * updates of the table schema to be performed with only one pass over the
1930  * data.
1931  *
1932  * ATPrepCmd performs phase 1.  A "work queue" entry is created for
1933  * each table to be affected (there may be multiple affected tables if the
1934  * commands traverse a table inheritance hierarchy).  Also we do preliminary
1935  * validation of the subcommands, including parse transformation of those
1936  * expressions that need to be evaluated with respect to the old table
1937  * schema.
1938  *
1939  * ATRewriteCatalogs performs phase 2 for each affected table (note that
1940  * phases 2 and 3 do no explicit recursion, since phase 1 already did it).
1941  * Certain subcommands need to be performed before others to avoid
1942  * unnecessary conflicts; for example, DROP COLUMN should come before
1943  * ADD COLUMN.  Therefore phase 1 divides the subcommands into multiple
1944  * lists, one for each logical "pass" of phase 2.
1945  *
1946  * ATRewriteTables performs phase 3 for those tables that need it.
1947  *
1948  * Thanks to the magic of MVCC, an error anywhere along the way rolls back
1949  * the whole operation; we don't have to do anything special to clean up.
1950  */
1951 void
1952 AlterTable(AlterTableStmt *stmt)
1953 {
1954         ATController(relation_openrv(stmt->relation, AccessExclusiveLock),
1955                                  stmt->cmds,
1956                                  interpretInhOption(stmt->relation->inhOpt));
1957 }
1958
1959 /*
1960  * AlterTableInternal
1961  *
1962  * ALTER TABLE with target specified by OID
1963  */
1964 void
1965 AlterTableInternal(Oid relid, List *cmds, bool recurse)
1966 {
1967         ATController(relation_open(relid, AccessExclusiveLock),
1968                                  cmds,
1969                                  recurse);
1970 }
1971
1972 static void
1973 ATController(Relation rel, List *cmds, bool recurse)
1974 {
1975         List       *wqueue = NIL;
1976         ListCell   *lcmd;
1977
1978         /* Phase 1: preliminary examination of commands, create work queue */
1979         foreach(lcmd, cmds)
1980         {
1981                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
1982
1983                 ATPrepCmd(&wqueue, rel, cmd, recurse, false);
1984         }
1985
1986         /* Close the relation, but keep lock until commit */
1987         relation_close(rel, NoLock);
1988
1989         /* Phase 2: update system catalogs */
1990         ATRewriteCatalogs(&wqueue);
1991
1992         /* Phase 3: scan/rewrite tables as needed */
1993         ATRewriteTables(&wqueue);
1994 }
1995
1996 /*
1997  * ATPrepCmd
1998  *
1999  * Traffic cop for ALTER TABLE Phase 1 operations, including simple
2000  * recursion and permission checks.
2001  *
2002  * Caller must have acquired AccessExclusiveLock on relation already.
2003  * This lock should be held until commit.
2004  */
2005 static void
2006 ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
2007                   bool recurse, bool recursing)
2008 {
2009         AlteredTableInfo *tab;
2010         int                     pass;
2011
2012         /* Find or create work queue entry for this table */
2013         tab = ATGetQueueEntry(wqueue, rel);
2014
2015         /*
2016          * Copy the original subcommand for each table.  This avoids conflicts
2017          * when different child tables need to make different parse
2018          * transformations (for example, the same column may have different column
2019          * numbers in different children).
2020          */
2021         cmd = copyObject(cmd);
2022
2023         /*
2024          * Do permissions checking, recursion to child tables if needed, and any
2025          * additional phase-1 processing needed.
2026          */
2027         switch (cmd->subtype)
2028         {
2029                 case AT_AddColumn:              /* ADD COLUMN */
2030                         ATSimplePermissions(rel, false);
2031                         /* Performs own recursion */
2032                         ATPrepAddColumn(wqueue, rel, recurse, cmd);
2033                         pass = AT_PASS_ADD_COL;
2034                         break;
2035                 case AT_ColumnDefault:  /* ALTER COLUMN DEFAULT */
2036
2037                         /*
2038                          * We allow defaults on views so that INSERT into a view can have
2039                          * default-ish behavior.  This works because the rewriter
2040                          * substitutes default values into INSERTs before it expands
2041                          * rules.
2042                          */
2043                         ATSimplePermissions(rel, true);
2044                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2045                         /* No command-specific prep needed */
2046                         pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
2047                         break;
2048                 case AT_DropNotNull:    /* ALTER COLUMN DROP NOT NULL */
2049                         ATSimplePermissions(rel, false);
2050                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2051                         /* No command-specific prep needed */
2052                         pass = AT_PASS_DROP;
2053                         break;
2054                 case AT_SetNotNull:             /* ALTER COLUMN SET NOT NULL */
2055                         ATSimplePermissions(rel, false);
2056                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2057                         /* No command-specific prep needed */
2058                         pass = AT_PASS_ADD_CONSTR;
2059                         break;
2060                 case AT_SetStatistics:  /* ALTER COLUMN STATISTICS */
2061                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2062                         /* Performs own permission checks */
2063                         ATPrepSetStatistics(rel, cmd->name, cmd->def);
2064                         pass = AT_PASS_COL_ATTRS;
2065                         break;
2066                 case AT_SetStorage:             /* ALTER COLUMN STORAGE */
2067                         ATSimplePermissions(rel, false);
2068                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2069                         /* No command-specific prep needed */
2070                         pass = AT_PASS_COL_ATTRS;
2071                         break;
2072                 case AT_DropColumn:             /* DROP COLUMN */
2073                         ATSimplePermissions(rel, false);
2074                         /* Recursion occurs during execution phase */
2075                         /* No command-specific prep needed except saving recurse flag */
2076                         if (recurse)
2077                                 cmd->subtype = AT_DropColumnRecurse;
2078                         pass = AT_PASS_DROP;
2079                         break;
2080                 case AT_AddIndex:               /* ADD INDEX */
2081                         ATSimplePermissions(rel, false);
2082                         /* This command never recurses */
2083                         /* No command-specific prep needed */
2084                         pass = AT_PASS_ADD_INDEX;
2085                         break;
2086                 case AT_AddConstraint:  /* ADD CONSTRAINT */
2087                         ATSimplePermissions(rel, false);
2088
2089                         /*
2090                          * Currently we recurse only for CHECK constraints, never for
2091                          * foreign-key constraints.  UNIQUE/PKEY constraints won't be seen
2092                          * here.
2093                          */
2094                         if (IsA(cmd->def, Constraint))
2095                                 ATSimpleRecursion(wqueue, rel, cmd, recurse);
2096                         /* No command-specific prep needed */
2097                         pass = AT_PASS_ADD_CONSTR;
2098                         break;
2099                 case AT_DropConstraint: /* DROP CONSTRAINT */
2100                         ATSimplePermissions(rel, false);
2101                         /* Performs own recursion */
2102                         ATPrepDropConstraint(wqueue, rel, recurse, cmd);
2103                         pass = AT_PASS_DROP;
2104                         break;
2105                 case AT_DropConstraintQuietly:  /* DROP CONSTRAINT for child */
2106                         ATSimplePermissions(rel, false);
2107                         ATSimpleRecursion(wqueue, rel, cmd, recurse);
2108                         /* No command-specific prep needed */
2109                         pass = AT_PASS_DROP;
2110                         break;
2111                 case AT_AlterColumnType:                /* ALTER COLUMN TYPE */
2112                         ATSimplePermissions(rel, false);
2113                         /* Performs own recursion */
2114                         ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd);
2115                         pass = AT_PASS_ALTER_TYPE;
2116                         break;
2117                 case AT_ChangeOwner:    /* ALTER OWNER */
2118                         /* This command never recurses */
2119                         /* No command-specific prep needed */
2120                         pass = AT_PASS_MISC;
2121                         break;
2122                 case AT_ClusterOn:              /* CLUSTER ON */
2123                 case AT_DropCluster:    /* SET WITHOUT CLUSTER */
2124                         ATSimplePermissions(rel, false);
2125                         /* These commands never recurse */
2126                         /* No command-specific prep needed */
2127                         pass = AT_PASS_MISC;
2128                         break;
2129                 case AT_DropOids:               /* SET WITHOUT OIDS */
2130                         ATSimplePermissions(rel, false);
2131                         /* Performs own recursion */
2132                         if (rel->rd_rel->relhasoids)
2133                         {
2134                                 AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
2135
2136                                 dropCmd->subtype = AT_DropColumn;
2137                                 dropCmd->name = pstrdup("oid");
2138                                 dropCmd->behavior = cmd->behavior;
2139                                 ATPrepCmd(wqueue, rel, dropCmd, recurse, false);
2140                         }
2141                         pass = AT_PASS_DROP;
2142                         break;
2143                 case AT_SetTableSpace:  /* SET TABLESPACE */
2144                         ATSimplePermissionsRelationOrIndex(rel);
2145                         /* This command never recurses */
2146                         ATPrepSetTableSpace(tab, rel, cmd->name);
2147                         pass = AT_PASS_MISC;    /* doesn't actually matter */
2148                         break;
2149                 case AT_SetRelOptions:  /* SET (...) */
2150                 case AT_ResetRelOptions:                /* RESET (...) */
2151                         ATSimplePermissionsRelationOrIndex(rel);
2152                         /* This command never recurses */
2153                         /* No command-specific prep needed */
2154                         pass = AT_PASS_MISC;
2155                         break;
2156                 case AT_EnableTrig:             /* ENABLE TRIGGER variants */
2157                 case AT_EnableTrigAll:
2158                 case AT_EnableTrigUser:
2159                 case AT_DisableTrig:    /* DISABLE TRIGGER variants */
2160                 case AT_DisableTrigAll:
2161                 case AT_DisableTrigUser:
2162                 case AT_AddInherit:             /* INHERIT / NO INHERIT */
2163                 case AT_DropInherit:
2164                         ATSimplePermissions(rel, false);
2165                         /* These commands never recurse */
2166                         /* No command-specific prep needed */
2167                         pass = AT_PASS_MISC;
2168                         break;
2169                 default:                                /* oops */
2170                         elog(ERROR, "unrecognized alter table type: %d",
2171                                  (int) cmd->subtype);
2172                         pass = 0;                       /* keep compiler quiet */
2173                         break;
2174         }
2175
2176         /* Add the subcommand to the appropriate list for phase 2 */
2177         tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
2178 }
2179
2180 /*
2181  * ATRewriteCatalogs
2182  *
2183  * Traffic cop for ALTER TABLE Phase 2 operations.      Subcommands are
2184  * dispatched in a "safe" execution order (designed to avoid unnecessary
2185  * conflicts).
2186  */
2187 static void
2188 ATRewriteCatalogs(List **wqueue)
2189 {
2190         int                     pass;
2191         ListCell   *ltab;
2192
2193         /*
2194          * We process all the tables "in parallel", one pass at a time.  This is
2195          * needed because we may have to propagate work from one table to another
2196          * (specifically, ALTER TYPE on a foreign key's PK has to dispatch the
2197          * re-adding of the foreign key constraint to the other table).  Work can
2198          * only be propagated into later passes, however.
2199          */
2200         for (pass = 0; pass < AT_NUM_PASSES; pass++)
2201         {
2202                 /* Go through each table that needs to be processed */
2203                 foreach(ltab, *wqueue)
2204                 {
2205                         AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2206                         List       *subcmds = tab->subcmds[pass];
2207                         Relation        rel;
2208                         ListCell   *lcmd;
2209
2210                         if (subcmds == NIL)
2211                                 continue;
2212
2213                         /*
2214                          * Exclusive lock was obtained by phase 1, needn't get it again
2215                          */
2216                         rel = relation_open(tab->relid, NoLock);
2217
2218                         foreach(lcmd, subcmds)
2219                                 ATExecCmd(tab, rel, (AlterTableCmd *) lfirst(lcmd));
2220
2221                         /*
2222                          * After the ALTER TYPE pass, do cleanup work (this is not done in
2223                          * ATExecAlterColumnType since it should be done only once if
2224                          * multiple columns of a table are altered).
2225                          */
2226                         if (pass == AT_PASS_ALTER_TYPE)
2227                                 ATPostAlterTypeCleanup(wqueue, tab);
2228
2229                         relation_close(rel, NoLock);
2230                 }
2231         }
2232
2233         /*
2234          * Check to see if a toast table must be added, if we executed any
2235          * subcommands that might have added a column or changed column storage.
2236          */
2237         foreach(ltab, *wqueue)
2238         {
2239                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2240
2241                 if (tab->relkind == RELKIND_RELATION &&
2242                         (tab->subcmds[AT_PASS_ADD_COL] ||
2243                          tab->subcmds[AT_PASS_ALTER_TYPE] ||
2244                          tab->subcmds[AT_PASS_COL_ATTRS]))
2245                         AlterTableCreateToastTable(tab->relid);
2246         }
2247 }
2248
2249 /*
2250  * ATExecCmd: dispatch a subcommand to appropriate execution routine
2251  */
2252 static void
2253 ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
2254 {
2255         switch (cmd->subtype)
2256         {
2257                 case AT_AddColumn:              /* ADD COLUMN */
2258                         ATExecAddColumn(tab, rel, (ColumnDef *) cmd->def);
2259                         break;
2260                 case AT_ColumnDefault:  /* ALTER COLUMN DEFAULT */
2261                         ATExecColumnDefault(rel, cmd->name, cmd->def);
2262                         break;
2263                 case AT_DropNotNull:    /* ALTER COLUMN DROP NOT NULL */
2264                         ATExecDropNotNull(rel, cmd->name);
2265                         break;
2266                 case AT_SetNotNull:             /* ALTER COLUMN SET NOT NULL */
2267                         ATExecSetNotNull(tab, rel, cmd->name);
2268                         break;
2269                 case AT_SetStatistics:  /* ALTER COLUMN STATISTICS */
2270                         ATExecSetStatistics(rel, cmd->name, cmd->def);
2271                         break;
2272                 case AT_SetStorage:             /* ALTER COLUMN STORAGE */
2273                         ATExecSetStorage(rel, cmd->name, cmd->def);
2274                         break;
2275                 case AT_DropColumn:             /* DROP COLUMN */
2276                         ATExecDropColumn(rel, cmd->name, cmd->behavior, false, false);
2277                         break;
2278                 case AT_DropColumnRecurse:              /* DROP COLUMN with recursion */
2279                         ATExecDropColumn(rel, cmd->name, cmd->behavior, true, false);
2280                         break;
2281                 case AT_AddIndex:               /* ADD INDEX */
2282                         ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false);
2283                         break;
2284                 case AT_ReAddIndex:             /* ADD INDEX */
2285                         ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true);
2286                         break;
2287                 case AT_AddConstraint:  /* ADD CONSTRAINT */
2288                         ATExecAddConstraint(tab, rel, cmd->def);
2289                         break;
2290                 case AT_DropConstraint: /* DROP CONSTRAINT */
2291                         ATExecDropConstraint(rel, cmd->name, cmd->behavior, false);
2292                         break;
2293                 case AT_DropConstraintQuietly:  /* DROP CONSTRAINT for child */
2294                         ATExecDropConstraint(rel, cmd->name, cmd->behavior, true);
2295                         break;
2296                 case AT_AlterColumnType:                /* ALTER COLUMN TYPE */
2297                         ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def);
2298                         break;
2299                 case AT_ChangeOwner:    /* ALTER OWNER */
2300                         ATExecChangeOwner(RelationGetRelid(rel),
2301                                                           get_roleid_checked(cmd->name),
2302                                                           false);
2303                         break;
2304                 case AT_ClusterOn:              /* CLUSTER ON */
2305                         ATExecClusterOn(rel, cmd->name);
2306                         break;
2307                 case AT_DropCluster:    /* SET WITHOUT CLUSTER */
2308                         ATExecDropCluster(rel);
2309                         break;
2310                 case AT_DropOids:               /* SET WITHOUT OIDS */
2311
2312                         /*
2313                          * Nothing to do here; we'll have generated a DropColumn
2314                          * subcommand to do the real work
2315                          */
2316                         break;
2317                 case AT_SetTableSpace:  /* SET TABLESPACE */
2318
2319                         /*
2320                          * Nothing to do here; Phase 3 does the work
2321                          */
2322                         break;
2323                 case AT_SetRelOptions:  /* SET (...) */
2324                         ATExecSetRelOptions(rel, (List *) cmd->def, false);
2325                         break;
2326                 case AT_ResetRelOptions:                /* RESET (...) */
2327                         ATExecSetRelOptions(rel, (List *) cmd->def, true);
2328                         break;
2329                 case AT_EnableTrig:             /* ENABLE TRIGGER name */
2330                         ATExecEnableDisableTrigger(rel, cmd->name, true, false);
2331                         break;
2332                 case AT_DisableTrig:    /* DISABLE TRIGGER name */
2333                         ATExecEnableDisableTrigger(rel, cmd->name, false, false);
2334                         break;
2335                 case AT_EnableTrigAll:  /* ENABLE TRIGGER ALL */
2336                         ATExecEnableDisableTrigger(rel, NULL, true, false);
2337                         break;
2338                 case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
2339                         ATExecEnableDisableTrigger(rel, NULL, false, false);
2340                         break;
2341                 case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
2342                         ATExecEnableDisableTrigger(rel, NULL, true, true);
2343                         break;
2344                 case AT_DisableTrigUser:                /* DISABLE TRIGGER USER */
2345                         ATExecEnableDisableTrigger(rel, NULL, false, true);
2346                         break;
2347                 case AT_AddInherit:
2348                         ATExecAddInherit(rel, (RangeVar *) cmd->def);
2349                         break;
2350                 case AT_DropInherit:
2351                         ATExecDropInherit(rel, (RangeVar *) cmd->def);
2352                         break;
2353                 default:                                /* oops */
2354                         elog(ERROR, "unrecognized alter table type: %d",
2355                                  (int) cmd->subtype);
2356                         break;
2357         }
2358
2359         /*
2360          * Bump the command counter to ensure the next subcommand in the sequence
2361          * can see the changes so far
2362          */
2363         CommandCounterIncrement();
2364 }
2365
2366 /*
2367  * ATRewriteTables: ALTER TABLE phase 3
2368  */
2369 static void
2370 ATRewriteTables(List **wqueue)
2371 {
2372         ListCell   *ltab;
2373
2374         /* Go through each table that needs to be checked or rewritten */
2375         foreach(ltab, *wqueue)
2376         {
2377                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2378
2379                 /*
2380                  * We only need to rewrite the table if at least one column needs to
2381                  * be recomputed.
2382                  */
2383                 if (tab->newvals != NIL)
2384                 {
2385                         /* Build a temporary relation and copy data */
2386                         Oid                     OIDNewHeap;
2387                         char            NewHeapName[NAMEDATALEN];
2388                         Oid                     NewTableSpace;
2389                         Relation        OldHeap;
2390                         ObjectAddress object;
2391
2392                         OldHeap = heap_open(tab->relid, NoLock);
2393
2394                         /*
2395                          * We can never allow rewriting of shared or nailed-in-cache
2396                          * relations, because we can't support changing their relfilenode
2397                          * values.
2398                          */
2399                         if (OldHeap->rd_rel->relisshared || OldHeap->rd_isnailed)
2400                                 ereport(ERROR,
2401                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2402                                                  errmsg("cannot rewrite system relation \"%s\"",
2403                                                                 RelationGetRelationName(OldHeap))));
2404
2405                         /*
2406                          * Don't allow rewrite on temp tables of other backends ... their
2407                          * local buffer manager is not going to cope.
2408                          */
2409                         if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
2410                                 ereport(ERROR,
2411                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2412                                 errmsg("cannot rewrite temporary tables of other sessions")));
2413
2414                         /*
2415                          * Select destination tablespace (same as original unless user
2416                          * requested a change)
2417                          */
2418                         if (tab->newTableSpace)
2419                                 NewTableSpace = tab->newTableSpace;
2420                         else
2421                                 NewTableSpace = OldHeap->rd_rel->reltablespace;
2422
2423                         heap_close(OldHeap, NoLock);
2424
2425                         /*
2426                          * Create the new heap, using a temporary name in the same
2427                          * namespace as the existing table.  NOTE: there is some risk of
2428                          * collision with user relnames.  Working around this seems more
2429                          * trouble than it's worth; in particular, we can't create the new
2430                          * heap in a different namespace from the old, or we will have
2431                          * problems with the TEMP status of temp tables.
2432                          */
2433                         snprintf(NewHeapName, sizeof(NewHeapName),
2434                                          "pg_temp_%u", tab->relid);
2435
2436                         OIDNewHeap = make_new_heap(tab->relid, NewHeapName, NewTableSpace);
2437
2438                         /*
2439                          * Copy the heap data into the new table with the desired
2440                          * modifications, and test the current data within the table
2441                          * against new constraints generated by ALTER TABLE commands.
2442                          */
2443                         ATRewriteTable(tab, OIDNewHeap);
2444
2445                         /* Swap the physical files of the old and new heaps. */
2446                         swap_relation_files(tab->relid, OIDNewHeap);
2447
2448                         CommandCounterIncrement();
2449
2450                         /* Destroy new heap with old filenode */
2451                         object.classId = RelationRelationId;
2452                         object.objectId = OIDNewHeap;
2453                         object.objectSubId = 0;
2454
2455                         /*
2456                          * The new relation is local to our transaction and we know
2457                          * nothing depends on it, so DROP_RESTRICT should be OK.
2458                          */
2459                         performDeletion(&object, DROP_RESTRICT);
2460                         /* performDeletion does CommandCounterIncrement at end */
2461
2462                         /*
2463                          * Rebuild each index on the relation (but not the toast table,
2464                          * which is all-new anyway).  We do not need
2465                          * CommandCounterIncrement() because reindex_relation does it.
2466                          */
2467                         reindex_relation(tab->relid, false);
2468                 }
2469                 else
2470                 {
2471                         /*
2472                          * Test the current data within the table against new constraints
2473                          * generated by ALTER TABLE commands, but don't rebuild data.
2474                          */
2475                         if (tab->constraints != NIL || tab->new_notnull)
2476                                 ATRewriteTable(tab, InvalidOid);
2477
2478                         /*
2479                          * If we had SET TABLESPACE but no reason to reconstruct tuples,
2480                          * just do a block-by-block copy.
2481                          */
2482                         if (tab->newTableSpace)
2483                                 ATExecSetTableSpace(tab->relid, tab->newTableSpace);
2484                 }
2485         }
2486
2487         /*
2488          * Foreign key constraints are checked in a final pass, since (a) it's
2489          * generally best to examine each one separately, and (b) it's at least
2490          * theoretically possible that we have changed both relations of the
2491          * foreign key, and we'd better have finished both rewrites before we try
2492          * to read the tables.
2493          */
2494         foreach(ltab, *wqueue)
2495         {
2496                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2497                 Relation        rel = NULL;
2498                 ListCell   *lcon;
2499
2500                 foreach(lcon, tab->constraints)
2501                 {
2502                         NewConstraint *con = lfirst(lcon);
2503
2504                         if (con->contype == CONSTR_FOREIGN)
2505                         {
2506                                 FkConstraint *fkconstraint = (FkConstraint *) con->qual;
2507                                 Relation        refrel;
2508
2509                                 if (rel == NULL)
2510                                 {
2511                                         /* Long since locked, no need for another */
2512                                         rel = heap_open(tab->relid, NoLock);
2513                                 }
2514
2515                                 refrel = heap_open(con->refrelid, RowShareLock);
2516
2517                                 validateForeignKeyConstraint(fkconstraint, rel, refrel);
2518
2519                                 heap_close(refrel, NoLock);
2520                         }
2521                 }
2522
2523                 if (rel)
2524                         heap_close(rel, NoLock);
2525         }
2526 }
2527
2528 /*
2529  * ATRewriteTable: scan or rewrite one table
2530  *
2531  * OIDNewHeap is InvalidOid if we don't need to rewrite
2532  */
2533 static void
2534 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
2535 {
2536         Relation        oldrel;
2537         Relation        newrel;
2538         TupleDesc       oldTupDesc;
2539         TupleDesc       newTupDesc;
2540         bool            needscan = false;
2541         List       *notnull_attrs;
2542         int                     i;
2543         ListCell   *l;
2544         EState     *estate;
2545
2546         /*
2547          * Open the relation(s).  We have surely already locked the existing
2548          * table.
2549          */
2550         oldrel = heap_open(tab->relid, NoLock);
2551         oldTupDesc = tab->oldDesc;
2552         newTupDesc = RelationGetDescr(oldrel);          /* includes all mods */
2553
2554         if (OidIsValid(OIDNewHeap))
2555                 newrel = heap_open(OIDNewHeap, AccessExclusiveLock);
2556         else
2557                 newrel = NULL;
2558
2559         /*
2560          * If we need to rewrite the table, the operation has to be propagated to
2561          * tables that use this table's rowtype as a column type.
2562          *
2563          * (Eventually this will probably become true for scans as well, but at
2564          * the moment a composite type does not enforce any constraints, so it's
2565          * not necessary/appropriate to enforce them just during ALTER.)
2566          */
2567         if (newrel)
2568                 find_composite_type_dependencies(oldrel->rd_rel->reltype,
2569                                                                                  RelationGetRelationName(oldrel));
2570
2571         /*
2572          * Generate the constraint and default execution states
2573          */
2574
2575         estate = CreateExecutorState();
2576
2577         /* Build the needed expression execution states */
2578         foreach(l, tab->constraints)
2579         {
2580                 NewConstraint *con = lfirst(l);
2581
2582                 switch (con->contype)
2583                 {
2584                         case CONSTR_CHECK:
2585                                 needscan = true;
2586                                 con->qualstate = (List *)
2587                                         ExecPrepareExpr((Expr *) con->qual, estate);
2588                                 break;
2589                         case CONSTR_FOREIGN:
2590                                 /* Nothing to do here */
2591                                 break;
2592                         default:
2593                                 elog(ERROR, "unrecognized constraint type: %d",
2594                                          (int) con->contype);
2595                 }
2596         }
2597
2598         foreach(l, tab->newvals)
2599         {
2600                 NewColumnValue *ex = lfirst(l);
2601
2602                 needscan = true;
2603
2604                 ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
2605         }
2606
2607         notnull_attrs = NIL;
2608         if (newrel || tab->new_notnull)
2609         {
2610                 /*
2611                  * If we are rebuilding the tuples OR if we added any new NOT NULL
2612                  * constraints, check all not-null constraints.  This is a bit of
2613                  * overkill but it minimizes risk of bugs, and heap_attisnull is a
2614                  * pretty cheap test anyway.
2615                  */
2616                 for (i = 0; i < newTupDesc->natts; i++)
2617                 {
2618                         if (newTupDesc->attrs[i]->attnotnull &&
2619                                 !newTupDesc->attrs[i]->attisdropped)
2620                                 notnull_attrs = lappend_int(notnull_attrs, i);
2621                 }
2622                 if (notnull_attrs)
2623                         needscan = true;
2624         }
2625
2626         if (needscan)
2627         {
2628                 ExprContext *econtext;
2629                 Datum      *values;
2630                 bool       *isnull;
2631                 TupleTableSlot *oldslot;
2632                 TupleTableSlot *newslot;
2633                 HeapScanDesc scan;
2634                 HeapTuple       tuple;
2635                 MemoryContext oldCxt;
2636                 List       *dropped_attrs = NIL;
2637                 ListCell   *lc;
2638
2639                 econtext = GetPerTupleExprContext(estate);
2640
2641                 /*
2642                  * Make tuple slots for old and new tuples.  Note that even when the
2643                  * tuples are the same, the tupDescs might not be (consider ADD COLUMN
2644                  * without a default).
2645                  */
2646                 oldslot = MakeSingleTupleTableSlot(oldTupDesc);
2647                 newslot = MakeSingleTupleTableSlot(newTupDesc);
2648
2649                 /* Preallocate values/isnull arrays */
2650                 i = Max(newTupDesc->natts, oldTupDesc->natts);
2651                 values = (Datum *) palloc(i * sizeof(Datum));
2652                 isnull = (bool *) palloc(i * sizeof(bool));
2653                 memset(values, 0, i * sizeof(Datum));
2654                 memset(isnull, true, i * sizeof(bool));
2655
2656                 /*
2657                  * Any attributes that are dropped according to the new tuple
2658                  * descriptor can be set to NULL. We precompute the list of dropped
2659                  * attributes to avoid needing to do so in the per-tuple loop.
2660                  */
2661                 for (i = 0; i < newTupDesc->natts; i++)
2662                 {
2663                         if (newTupDesc->attrs[i]->attisdropped)
2664                                 dropped_attrs = lappend_int(dropped_attrs, i);
2665                 }
2666
2667                 /*
2668                  * Scan through the rows, generating a new row if needed and then
2669                  * checking all the constraints.
2670                  */
2671                 scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
2672
2673                 /*
2674                  * Switch to per-tuple memory context and reset it for each tuple
2675                  * produced, so we don't leak memory.
2676                  */
2677                 oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
2678
2679                 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
2680                 {
2681                         if (newrel)
2682                         {
2683                                 Oid                     tupOid = InvalidOid;
2684
2685                                 /* Extract data from old tuple */
2686                                 heap_deform_tuple(tuple, oldTupDesc, values, isnull);
2687                                 if (oldTupDesc->tdhasoid)
2688                                         tupOid = HeapTupleGetOid(tuple);
2689
2690                                 /* Set dropped attributes to null in new tuple */
2691                                 foreach(lc, dropped_attrs)
2692                                         isnull[lfirst_int(lc)] = true;
2693
2694                                 /*
2695                                  * Process supplied expressions to replace selected columns.
2696                                  * Expression inputs come from the old tuple.
2697                                  */
2698                                 ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
2699                                 econtext->ecxt_scantuple = oldslot;
2700
2701                                 foreach(l, tab->newvals)
2702                                 {
2703                                         NewColumnValue *ex = lfirst(l);
2704
2705                                         values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
2706                                                                                                                   econtext,
2707                                                                                                          &isnull[ex->attnum - 1],
2708                                                                                                                   NULL);
2709                                 }
2710
2711                                 /*
2712                                  * Form the new tuple. Note that we don't explicitly pfree it,
2713                                  * since the per-tuple memory context will be reset shortly.
2714                                  */
2715                                 tuple = heap_form_tuple(newTupDesc, values, isnull);
2716
2717                                 /* Preserve OID, if any */
2718                                 if (newTupDesc->tdhasoid)
2719                                         HeapTupleSetOid(tuple, tupOid);
2720                         }
2721
2722                         /* Now check any constraints on the possibly-changed tuple */
2723                         ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
2724                         econtext->ecxt_scantuple = newslot;
2725
2726                         foreach(l, notnull_attrs)
2727                         {
2728                                 int                     attn = lfirst_int(l);
2729
2730                                 if (heap_attisnull(tuple, attn + 1))
2731                                         ereport(ERROR,
2732                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
2733                                                          errmsg("column \"%s\" contains null values",
2734                                                                 NameStr(newTupDesc->attrs[attn]->attname))));
2735                         }
2736
2737                         foreach(l, tab->constraints)
2738                         {
2739                                 NewConstraint *con = lfirst(l);
2740
2741                                 switch (con->contype)
2742                                 {
2743                                         case CONSTR_CHECK:
2744                                                 if (!ExecQual(con->qualstate, econtext, true))
2745                                                         ereport(ERROR,
2746                                                                         (errcode(ERRCODE_CHECK_VIOLATION),
2747                                                                          errmsg("check constraint \"%s\" is violated by some row",
2748                                                                                         con->name)));
2749                                                 break;
2750                                         case CONSTR_FOREIGN:
2751                                                 /* Nothing to do here */
2752                                                 break;
2753                                         default:
2754                                                 elog(ERROR, "unrecognized constraint type: %d",
2755                                                          (int) con->contype);
2756                                 }
2757                         }
2758
2759                         /* Write the tuple out to the new relation */
2760                         if (newrel)
2761                                 simple_heap_insert(newrel, tuple);
2762
2763                         ResetExprContext(econtext);
2764
2765                         CHECK_FOR_INTERRUPTS();
2766                 }
2767
2768                 MemoryContextSwitchTo(oldCxt);
2769                 heap_endscan(scan);
2770
2771                 ExecDropSingleTupleTableSlot(oldslot);
2772                 ExecDropSingleTupleTableSlot(newslot);
2773         }
2774
2775         FreeExecutorState(estate);
2776
2777         heap_close(oldrel, NoLock);
2778         if (newrel)
2779                 heap_close(newrel, NoLock);
2780 }
2781
2782 /*
2783  * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
2784  */
2785 static AlteredTableInfo *
2786 ATGetQueueEntry(List **wqueue, Relation rel)
2787 {
2788         Oid                     relid = RelationGetRelid(rel);
2789         AlteredTableInfo *tab;
2790         ListCell   *ltab;
2791
2792         foreach(ltab, *wqueue)
2793         {
2794                 tab = (AlteredTableInfo *) lfirst(ltab);
2795                 if (tab->relid == relid)
2796                         return tab;
2797         }
2798
2799         /*
2800          * Not there, so add it.  Note that we make a copy of the relation's
2801          * existing descriptor before anything interesting can happen to it.
2802          */
2803         tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
2804         tab->relid = relid;
2805         tab->relkind = rel->rd_rel->relkind;
2806         tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));
2807
2808         *wqueue = lappend(*wqueue, tab);
2809
2810         return tab;
2811 }
2812
2813 /*
2814  * ATSimplePermissions
2815  *
2816  * - Ensure that it is a relation (or possibly a view)
2817  * - Ensure this user is the owner
2818  * - Ensure that it is not a system table
2819  */
2820 static void
2821 ATSimplePermissions(Relation rel, bool allowView)
2822 {
2823         if (rel->rd_rel->relkind != RELKIND_RELATION)
2824         {
2825                 if (allowView)
2826                 {
2827                         if (rel->rd_rel->relkind != RELKIND_VIEW)
2828                                 ereport(ERROR,
2829                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2830                                                  errmsg("\"%s\" is not a table or view",
2831                                                                 RelationGetRelationName(rel))));
2832                 }
2833                 else
2834                         ereport(ERROR,
2835                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2836                                          errmsg("\"%s\" is not a table",
2837                                                         RelationGetRelationName(rel))));
2838         }
2839
2840         /* Permissions checks */
2841         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
2842                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
2843                                            RelationGetRelationName(rel));
2844
2845         if (!allowSystemTableMods && IsSystemRelation(rel))
2846                 ereport(ERROR,
2847                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2848                                  errmsg("permission denied: \"%s\" is a system catalog",
2849                                                 RelationGetRelationName(rel))));
2850 }
2851
2852 /*
2853  * ATSimplePermissionsRelationOrIndex
2854  *
2855  * - Ensure that it is a relation or an index
2856  * - Ensure this user is the owner
2857  * - Ensure that it is not a system table
2858  */
2859 static void
2860 ATSimplePermissionsRelationOrIndex(Relation rel)
2861 {
2862         if (rel->rd_rel->relkind != RELKIND_RELATION &&
2863                 rel->rd_rel->relkind != RELKIND_INDEX)
2864                 ereport(ERROR,
2865                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2866                                  errmsg("\"%s\" is not a table or index",
2867                                                 RelationGetRelationName(rel))));
2868
2869         /* Permissions checks */
2870         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
2871                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
2872                                            RelationGetRelationName(rel));
2873
2874         if (!allowSystemTableMods && IsSystemRelation(rel))
2875                 ereport(ERROR,
2876                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2877                                  errmsg("permission denied: \"%s\" is a system catalog",
2878                                                 RelationGetRelationName(rel))));
2879 }
2880
2881 /*
2882  * ATSimpleRecursion
2883  *
2884  * Simple table recursion sufficient for most ALTER TABLE operations.
2885  * All direct and indirect children are processed in an unspecified order.
2886  * Note that if a child inherits from the original table via multiple
2887  * inheritance paths, it will be visited just once.
2888  */
2889 static void
2890 ATSimpleRecursion(List **wqueue, Relation rel,
2891                                   AlterTableCmd *cmd, bool recurse)
2892 {
2893         /*
2894          * Propagate to children if desired.  Non-table relations never have
2895          * children, so no need to search in that case.
2896          */
2897         if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
2898         {
2899                 Oid                     relid = RelationGetRelid(rel);
2900                 ListCell   *child;
2901                 List       *children;
2902
2903                 /* this routine is actually in the planner */
2904                 children = find_all_inheritors(relid);
2905
2906                 /*
2907                  * find_all_inheritors does the recursive search of the inheritance
2908                  * hierarchy, so all we have to do is process all of the relids in the
2909                  * list that it returns.
2910                  */
2911                 foreach(child, children)
2912                 {
2913                         Oid                     childrelid = lfirst_oid(child);
2914                         Relation        childrel;
2915
2916                         if (childrelid == relid)
2917                                 continue;
2918                         childrel = relation_open(childrelid, AccessExclusiveLock);
2919                         ATPrepCmd(wqueue, childrel, cmd, false, true);
2920                         relation_close(childrel, NoLock);
2921                 }
2922         }
2923 }
2924
2925 /*
2926  * ATOneLevelRecursion
2927  *
2928  * Here, we visit only direct inheritance children.  It is expected that
2929  * the command's prep routine will recurse again to find indirect children.
2930  * When using this technique, a multiply-inheriting child will be visited
2931  * multiple times.
2932  */
2933 static void
2934 ATOneLevelRecursion(List **wqueue, Relation rel,
2935                                         AlterTableCmd *cmd)
2936 {
2937         Oid                     relid = RelationGetRelid(rel);
2938         ListCell   *child;
2939         List       *children;
2940
2941         /* this routine is actually in the planner */
2942         children = find_inheritance_children(relid);
2943
2944         foreach(child, children)
2945         {
2946                 Oid                     childrelid = lfirst_oid(child);
2947                 Relation        childrel;
2948
2949                 childrel = relation_open(childrelid, AccessExclusiveLock);
2950                 ATPrepCmd(wqueue, childrel, cmd, true, true);
2951                 relation_close(childrel, NoLock);
2952         }
2953 }
2954
2955
2956 /*
2957  * find_composite_type_dependencies
2958  *
2959  * Check to see if a table's rowtype is being used as a column in some
2960  * other table (possibly nested several levels deep in composite types!).
2961  * Eventually, we'd like to propagate the check or rewrite operation
2962  * into other such tables, but for now, just error out if we find any.
2963  *
2964  * We assume that functions and views depending on the type are not reasons
2965  * to reject the ALTER.  (How safe is this really?)
2966  */
2967 static void
2968 find_composite_type_dependencies(Oid typeOid, const char *origTblName)
2969 {
2970         Relation        depRel;
2971         ScanKeyData key[2];
2972         SysScanDesc depScan;
2973         HeapTuple       depTup;
2974
2975         /*
2976          * We scan pg_depend to find those things that depend on the rowtype. (We
2977          * assume we can ignore refobjsubid for a rowtype.)
2978          */
2979         depRel = heap_open(DependRelationId, AccessShareLock);
2980
2981         ScanKeyInit(&key[0],
2982                                 Anum_pg_depend_refclassid,
2983                                 BTEqualStrategyNumber, F_OIDEQ,
2984                                 ObjectIdGetDatum(TypeRelationId));
2985         ScanKeyInit(&key[1],
2986                                 Anum_pg_depend_refobjid,
2987                                 BTEqualStrategyNumber, F_OIDEQ,
2988                                 ObjectIdGetDatum(typeOid));
2989
2990         depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
2991                                                                  SnapshotNow, 2, key);
2992
2993         while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
2994         {
2995                 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
2996                 Relation        rel;
2997                 Form_pg_attribute att;
2998
2999                 /* Ignore dependees that aren't user columns of relations */
3000                 /* (we assume system columns are never of rowtypes) */
3001                 if (pg_depend->classid != RelationRelationId ||
3002                         pg_depend->objsubid <= 0)
3003                         continue;
3004
3005                 rel = relation_open(pg_depend->objid, AccessShareLock);
3006                 att = rel->rd_att->attrs[pg_depend->objsubid - 1];
3007
3008                 if (rel->rd_rel->relkind == RELKIND_RELATION)
3009                 {
3010                         ereport(ERROR,
3011                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3012                                          errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
3013                                                         origTblName,
3014                                                         RelationGetRelationName(rel),
3015                                                         NameStr(att->attname))));
3016                 }
3017                 else if (OidIsValid(rel->rd_rel->reltype))
3018                 {
3019                         /*
3020                          * A view or composite type itself isn't a problem, but we must
3021                          * recursively check for indirect dependencies via its rowtype.
3022                          */
3023                         find_composite_type_dependencies(rel->rd_rel->reltype,
3024                                                                                          origTblName);
3025                 }
3026
3027                 relation_close(rel, AccessShareLock);
3028         }
3029
3030         systable_endscan(depScan);
3031
3032         relation_close(depRel, AccessShareLock);
3033 }
3034
3035
3036 /*
3037  * ALTER TABLE ADD COLUMN
3038  *
3039  * Adds an additional attribute to a relation making the assumption that
3040  * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
3041  * AT_AddColumn AlterTableCmd by analyze.c and added as independent
3042  * AlterTableCmd's.
3043  */
3044 static void
3045 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
3046                                 AlterTableCmd *cmd)
3047 {
3048         /*
3049          * Recurse to add the column to child classes, if requested.
3050          *
3051          * We must recurse one level at a time, so that multiply-inheriting
3052          * children are visited the right number of times and end up with the
3053          * right attinhcount.
3054          */
3055         if (recurse)
3056         {
3057                 AlterTableCmd *childCmd = copyObject(cmd);
3058                 ColumnDef  *colDefChild = (ColumnDef *) childCmd->def;
3059
3060                 /* Child should see column as singly inherited */
3061                 colDefChild->inhcount = 1;
3062                 colDefChild->is_local = false;
3063
3064                 ATOneLevelRecursion(wqueue, rel, childCmd);
3065         }
3066         else
3067         {
3068                 /*
3069                  * If we are told not to recurse, there had better not be any child
3070                  * tables; else the addition would put them out of step.
3071                  */
3072                 if (find_inheritance_children(RelationGetRelid(rel)) != NIL)
3073                         ereport(ERROR,
3074                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3075                                          errmsg("column must be added to child tables too")));
3076         }
3077 }
3078
3079 static void
3080 ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
3081                                 ColumnDef *colDef)
3082 {
3083         Oid                     myrelid = RelationGetRelid(rel);
3084         Relation        pgclass,
3085                                 attrdesc;
3086         HeapTuple       reltup;
3087         HeapTuple       attributeTuple;
3088         Form_pg_attribute attribute;
3089         FormData_pg_attribute attributeD;
3090         int                     i;
3091         int                     minattnum,
3092                                 maxatts;
3093         HeapTuple       typeTuple;
3094         Oid                     typeOid;
3095         Form_pg_type tform;
3096         Expr       *defval;
3097
3098         attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
3099
3100         /*
3101          * Are we adding the column to a recursion child?  If so, check whether to
3102          * merge with an existing definition for the column.
3103          */
3104         if (colDef->inhcount > 0)
3105         {
3106                 HeapTuple       tuple;
3107
3108                 /* Does child already have a column by this name? */
3109                 tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
3110                 if (HeapTupleIsValid(tuple))
3111                 {
3112                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
3113
3114                         /* Okay if child matches by type */
3115                         if (typenameTypeId(NULL, colDef->typename) != childatt->atttypid ||
3116                                 colDef->typename->typmod != childatt->atttypmod)
3117                                 ereport(ERROR,
3118                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
3119                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
3120                                                         RelationGetRelationName(rel), colDef->colname)));
3121
3122                         /* Bump the existing child att's inhcount */
3123                         childatt->attinhcount++;
3124                         simple_heap_update(attrdesc, &tuple->t_self, tuple);
3125                         CatalogUpdateIndexes(attrdesc, tuple);
3126
3127                         heap_freetuple(tuple);
3128
3129                         /* Inform the user about the merge */
3130                         ereport(NOTICE,
3131                           (errmsg("merging definition of column \"%s\" for child \"%s\"",
3132                                           colDef->colname, RelationGetRelationName(rel))));
3133
3134                         heap_close(attrdesc, RowExclusiveLock);
3135                         return;
3136                 }
3137         }
3138
3139         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
3140
3141         reltup = SearchSysCacheCopy(RELOID,
3142                                                                 ObjectIdGetDatum(myrelid),
3143                                                                 0, 0, 0);
3144         if (!HeapTupleIsValid(reltup))
3145                 elog(ERROR, "cache lookup failed for relation %u", myrelid);
3146
3147         /*
3148          * this test is deliberately not attisdropped-aware, since if one tries to
3149          * add a column matching a dropped column name, it's gonna fail anyway.
3150          */
3151         if (SearchSysCacheExists(ATTNAME,
3152                                                          ObjectIdGetDatum(myrelid),
3153                                                          PointerGetDatum(colDef->colname),
3154                                                          0, 0))
3155                 ereport(ERROR,
3156                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
3157                                  errmsg("column \"%s\" of relation \"%s\" already exists",
3158                                                 colDef->colname, RelationGetRelationName(rel))));
3159
3160         minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
3161         maxatts = minattnum + 1;
3162         if (maxatts > MaxHeapAttributeNumber)
3163                 ereport(ERROR,
3164                                 (errcode(ERRCODE_TOO_MANY_COLUMNS),
3165                                  errmsg("tables can have at most %d columns",
3166                                                 MaxHeapAttributeNumber)));
3167         i = minattnum + 1;
3168
3169         typeTuple = typenameType(NULL, colDef->typename);
3170         tform = (Form_pg_type) GETSTRUCT(typeTuple);
3171         typeOid = HeapTupleGetOid(typeTuple);
3172
3173         /* make sure datatype is legal for a column */
3174         CheckAttributeType(colDef->colname, typeOid);
3175
3176         attributeTuple = heap_addheader(Natts_pg_attribute,
3177                                                                         false,
3178                                                                         ATTRIBUTE_TUPLE_SIZE,
3179                                                                         (void *) &attributeD);
3180
3181         attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
3182
3183         attribute->attrelid = myrelid;
3184         namestrcpy(&(attribute->attname), colDef->colname);
3185         attribute->atttypid = typeOid;
3186         attribute->attstattarget = -1;
3187         attribute->attlen = tform->typlen;
3188         attribute->attcacheoff = -1;
3189         attribute->atttypmod = colDef->typename->typmod;
3190         attribute->attnum = i;
3191         attribute->attbyval = tform->typbyval;
3192         attribute->attndims = list_length(colDef->typename->arrayBounds);
3193         attribute->attstorage = tform->typstorage;
3194         attribute->attalign = tform->typalign;
3195         attribute->attnotnull = colDef->is_not_null;
3196         attribute->atthasdef = false;
3197         attribute->attisdropped = false;
3198         attribute->attislocal = colDef->is_local;
3199         attribute->attinhcount = colDef->inhcount;
3200
3201         ReleaseSysCache(typeTuple);
3202
3203         simple_heap_insert(attrdesc, attributeTuple);
3204
3205         /* Update indexes on pg_attribute */
3206         CatalogUpdateIndexes(attrdesc, attributeTuple);
3207
3208         heap_close(attrdesc, RowExclusiveLock);
3209
3210         /*
3211          * Update number of attributes in pg_class tuple
3212          */
3213         ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
3214
3215         simple_heap_update(pgclass, &reltup->t_self, reltup);
3216
3217         /* keep catalog indexes current */
3218         CatalogUpdateIndexes(pgclass, reltup);
3219
3220         heap_freetuple(reltup);
3221
3222         heap_close(pgclass, RowExclusiveLock);
3223
3224         /* Make the attribute's catalog entry visible */
3225         CommandCounterIncrement();
3226
3227         /*
3228          * Store the DEFAULT, if any, in the catalogs
3229          */
3230         if (colDef->raw_default)
3231         {
3232                 RawColumnDefault *rawEnt;
3233
3234                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
3235                 rawEnt->attnum = attribute->attnum;
3236                 rawEnt->raw_default = copyObject(colDef->raw_default);
3237
3238                 /*
3239                  * This function is intended for CREATE TABLE, so it processes a
3240                  * _list_ of defaults, but we just do one.
3241                  */
3242                 AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
3243
3244                 /* Make the additional catalog changes visible */
3245                 CommandCounterIncrement();
3246         }
3247
3248         /*
3249          * Tell Phase 3 to fill in the default expression, if there is one.
3250          *
3251          * If there is no default, Phase 3 doesn't have to do anything, because
3252          * that effectively means that the default is NULL.  The heap tuple access
3253          * routines always check for attnum > # of attributes in tuple, and return
3254          * NULL if so, so without any modification of the tuple data we will get
3255          * the effect of NULL values in the new column.
3256          *
3257          * An exception occurs when the new column is of a domain type: the domain
3258          * might have a NOT NULL constraint, or a check constraint that indirectly
3259          * rejects nulls.  If there are any domain constraints then we construct
3260          * an explicit NULL default value that will be passed through
3261          * CoerceToDomain processing.  (This is a tad inefficient, since it causes
3262          * rewriting the table which we really don't have to do, but the present
3263          * design of domain processing doesn't offer any simple way of checking
3264          * the constraints more directly.)
3265          *
3266          * Note: we use build_column_default, and not just the cooked default
3267          * returned by AddRelationRawConstraints, so that the right thing happens
3268          * when a datatype's default applies.
3269          */
3270         defval = (Expr *) build_column_default(rel, attribute->attnum);
3271
3272         if (!defval && GetDomainConstraints(typeOid) != NIL)
3273         {
3274                 Oid                     basetype = getBaseType(typeOid);
3275
3276                 defval = (Expr *) makeNullConst(basetype);
3277                 defval = (Expr *) coerce_to_target_type(NULL,
3278                                                                                                 (Node *) defval,
3279                                                                                                 basetype,
3280                                                                                                 typeOid,
3281                                                                                                 colDef->typename->typmod,
3282                                                                                                 COERCION_ASSIGNMENT,
3283                                                                                                 COERCE_IMPLICIT_CAST);
3284                 if (defval == NULL)             /* should not happen */
3285                         elog(ERROR, "failed to coerce base type to domain");
3286         }
3287
3288         if (defval)
3289         {
3290                 NewColumnValue *newval;
3291
3292                 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
3293                 newval->attnum = attribute->attnum;
3294                 newval->expr = defval;
3295
3296                 tab->newvals = lappend(tab->newvals, newval);
3297         }
3298
3299         /*
3300          * Add needed dependency entries for the new column.
3301          */
3302         add_column_datatype_dependency(myrelid, i, attribute->atttypid);
3303 }
3304
3305 /*
3306  * Install a column's dependency on its datatype.
3307  */
3308 static void
3309 add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
3310 {
3311         ObjectAddress myself,
3312                                 referenced;
3313
3314         myself.classId = RelationRelationId;
3315         myself.objectId = relid;
3316         myself.objectSubId = attnum;
3317         referenced.classId = TypeRelationId;
3318         referenced.objectId = typid;
3319         referenced.objectSubId = 0;
3320         recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3321 }
3322
3323 /*
3324  * ALTER TABLE ALTER COLUMN DROP NOT NULL
3325  */
3326 static void
3327 ATExecDropNotNull(Relation rel, const char *colName)
3328 {
3329         HeapTuple       tuple;
3330         AttrNumber      attnum;
3331         Relation        attr_rel;
3332         List       *indexoidlist;
3333         ListCell   *indexoidscan;
3334
3335         /*
3336          * lookup the attribute
3337          */
3338         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3339
3340         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3341
3342         if (!HeapTupleIsValid(tuple))
3343                 ereport(ERROR,
3344                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3345                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3346                                                 colName, RelationGetRelationName(rel))));
3347
3348         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
3349
3350         /* Prevent them from altering a system attribute */
3351         if (attnum <= 0)
3352                 ereport(ERROR,
3353                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3354                                  errmsg("cannot alter system column \"%s\"",
3355                                                 colName)));
3356
3357         /*
3358          * Check that the attribute is not in a primary key
3359          */
3360
3361         /* Loop over all indexes on the relation */
3362         indexoidlist = RelationGetIndexList(rel);
3363
3364         foreach(indexoidscan, indexoidlist)
3365         {
3366                 Oid                     indexoid = lfirst_oid(indexoidscan);
3367                 HeapTuple       indexTuple;
3368                 Form_pg_index indexStruct;
3369                 int                     i;
3370
3371                 indexTuple = SearchSysCache(INDEXRELID,
3372                                                                         ObjectIdGetDatum(indexoid),
3373                                                                         0, 0, 0);
3374                 if (!HeapTupleIsValid(indexTuple))
3375                         elog(ERROR, "cache lookup failed for index %u", indexoid);
3376                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
3377
3378                 /* If the index is not a primary key, skip the check */
3379                 if (indexStruct->indisprimary)
3380                 {
3381                         /*
3382                          * Loop over each attribute in the primary key and see if it
3383                          * matches the to-be-altered attribute
3384                          */
3385                         for (i = 0; i < indexStruct->indnatts; i++)
3386                         {
3387                                 if (indexStruct->indkey.values[i] == attnum)
3388                                         ereport(ERROR,
3389                                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3390                                                          errmsg("column \"%s\" is in a primary key",
3391                                                                         colName)));
3392                         }
3393                 }
3394
3395                 ReleaseSysCache(indexTuple);
3396         }
3397
3398         list_free(indexoidlist);
3399
3400         /*
3401          * Okay, actually perform the catalog change ... if needed
3402          */
3403         if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
3404         {
3405                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;
3406
3407                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3408
3409                 /* keep the system catalog indexes current */
3410                 CatalogUpdateIndexes(attr_rel, tuple);
3411         }
3412
3413         heap_close(attr_rel, RowExclusiveLock);
3414 }
3415
3416 /*
3417  * ALTER TABLE ALTER COLUMN SET NOT NULL
3418  */
3419 static void
3420 ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
3421                                  const char *colName)
3422 {
3423         HeapTuple       tuple;
3424         AttrNumber      attnum;
3425         Relation        attr_rel;
3426
3427         /*
3428          * lookup the attribute
3429          */
3430         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3431
3432         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3433
3434         if (!HeapTupleIsValid(tuple))
3435                 ereport(ERROR,
3436                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3437                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3438                                                 colName, RelationGetRelationName(rel))));
3439
3440         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
3441
3442         /* Prevent them from altering a system attribute */
3443         if (attnum <= 0)
3444                 ereport(ERROR,
3445                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3446                                  errmsg("cannot alter system column \"%s\"",
3447                                                 colName)));
3448
3449         /*
3450          * Okay, actually perform the catalog change ... if needed
3451          */
3452         if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
3453         {
3454                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;
3455
3456                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3457
3458                 /* keep the system catalog indexes current */
3459                 CatalogUpdateIndexes(attr_rel, tuple);
3460
3461                 /* Tell Phase 3 it needs to test the constraint */
3462                 tab->new_notnull = true;
3463         }
3464
3465         heap_close(attr_rel, RowExclusiveLock);
3466 }
3467
3468 /*
3469  * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
3470  */
3471 static void
3472 ATExecColumnDefault(Relation rel, const char *colName,
3473                                         Node *newDefault)
3474 {
3475         AttrNumber      attnum;
3476
3477         /*
3478          * get the number of the attribute
3479          */
3480         attnum = get_attnum(RelationGetRelid(rel), colName);
3481         if (attnum == InvalidAttrNumber)
3482                 ereport(ERROR,
3483                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3484                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3485                                                 colName, RelationGetRelationName(rel))));
3486
3487         /* Prevent them from altering a system attribute */
3488         if (attnum <= 0)
3489                 ereport(ERROR,
3490                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3491                                  errmsg("cannot alter system column \"%s\"",
3492                                                 colName)));
3493
3494         /*
3495          * Remove any old default for the column.  We use RESTRICT here for
3496          * safety, but at present we do not expect anything to depend on the
3497          * default.
3498          */
3499         RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
3500
3501         if (newDefault)
3502         {
3503                 /* SET DEFAULT */
3504                 RawColumnDefault *rawEnt;
3505
3506                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
3507                 rawEnt->attnum = attnum;
3508                 rawEnt->raw_default = newDefault;
3509
3510                 /*
3511                  * This function is intended for CREATE TABLE, so it processes a
3512                  * _list_ of defaults, but we just do one.
3513                  */
3514                 AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
3515         }
3516 }
3517
3518 /*
3519  * ALTER TABLE ALTER COLUMN SET STATISTICS
3520  */
3521 static void
3522 ATPrepSetStatistics(Relation rel, const char *colName, Node *flagValue)
3523 {
3524         /*
3525          * We do our own permission checking because (a) we want to allow SET
3526          * STATISTICS on indexes (for expressional index columns), and (b) we want
3527          * to allow SET STATISTICS on system catalogs without requiring
3528          * allowSystemTableMods to be turned on.
3529          */
3530         if (rel->rd_rel->relkind != RELKIND_RELATION &&
3531                 rel->rd_rel->relkind != RELKIND_INDEX)
3532                 ereport(ERROR,
3533                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3534                                  errmsg("\"%s\" is not a table or index",
3535                                                 RelationGetRelationName(rel))));
3536
3537         /* Permissions checks */
3538         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
3539                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
3540                                            RelationGetRelationName(rel));
3541 }
3542
3543 static void
3544 ATExecSetStatistics(Relation rel, const char *colName, Node *newValue)
3545 {
3546         int                     newtarget;
3547         Relation        attrelation;
3548         HeapTuple       tuple;
3549         Form_pg_attribute attrtuple;
3550
3551         Assert(IsA(newValue, Integer));
3552         newtarget = intVal(newValue);
3553
3554         /*
3555          * Limit target to a sane range
3556          */
3557         if (newtarget < -1)
3558         {
3559                 ereport(ERROR,
3560                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3561                                  errmsg("statistics target %d is too low",
3562                                                 newtarget)));
3563         }
3564         else if (newtarget > 1000)
3565         {
3566                 newtarget = 1000;
3567                 ereport(WARNING,
3568                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3569                                  errmsg("lowering statistics target to %d",
3570                                                 newtarget)));
3571         }
3572
3573         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
3574
3575         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3576
3577         if (!HeapTupleIsValid(tuple))
3578                 ereport(ERROR,
3579                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3580                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3581                                                 colName, RelationGetRelationName(rel))));
3582         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
3583
3584         if (attrtuple->attnum <= 0)
3585                 ereport(ERROR,
3586                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3587                                  errmsg("cannot alter system column \"%s\"",
3588                                                 colName)));
3589
3590         attrtuple->attstattarget = newtarget;
3591
3592         simple_heap_update(attrelation, &tuple->t_self, tuple);
3593
3594         /* keep system catalog indexes current */
3595         CatalogUpdateIndexes(attrelation, tuple);
3596
3597         heap_freetuple(tuple);
3598
3599         heap_close(attrelation, RowExclusiveLock);
3600 }
3601
3602 /*
3603  * ALTER TABLE ALTER COLUMN SET STORAGE
3604  */
3605 static void
3606 ATExecSetStorage(Relation rel, const char *colName, Node *newValue)
3607 {
3608         char       *storagemode;
3609         char            newstorage;
3610         Relation        attrelation;
3611         HeapTuple       tuple;
3612         Form_pg_attribute attrtuple;
3613
3614         Assert(IsA(newValue, String));
3615         storagemode = strVal(newValue);
3616
3617         if (pg_strcasecmp(storagemode, "plain") == 0)
3618                 newstorage = 'p';
3619         else if (pg_strcasecmp(storagemode, "external") == 0)
3620                 newstorage = 'e';
3621         else if (pg_strcasecmp(storagemode, "extended") == 0)
3622                 newstorage = 'x';
3623         else if (pg_strcasecmp(storagemode, "main") == 0)
3624                 newstorage = 'm';
3625         else
3626         {
3627                 ereport(ERROR,
3628                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3629                                  errmsg("invalid storage type \"%s\"",
3630                                                 storagemode)));
3631                 newstorage = 0;                 /* keep compiler quiet */
3632         }
3633
3634         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
3635
3636         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3637
3638         if (!HeapTupleIsValid(tuple))
3639                 ereport(ERROR,
3640                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3641                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3642                                                 colName, RelationGetRelationName(rel))));
3643         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
3644
3645         if (attrtuple->attnum <= 0)
3646                 ereport(ERROR,
3647                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3648                                  errmsg("cannot alter system column \"%s\"",
3649                                                 colName)));
3650
3651         /*
3652          * safety check: do not allow toasted storage modes unless column datatype
3653          * is TOAST-aware.
3654          */
3655         if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
3656                 attrtuple->attstorage = newstorage;
3657         else
3658                 ereport(ERROR,
3659                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3660                                  errmsg("column data type %s can only have storage PLAIN",
3661                                                 format_type_be(attrtuple->atttypid))));
3662
3663         simple_heap_update(attrelation, &tuple->t_self, tuple);
3664
3665         /* keep system catalog indexes current */
3666         CatalogUpdateIndexes(attrelation, tuple);
3667
3668         heap_freetuple(tuple);
3669
3670         heap_close(attrelation, RowExclusiveLock);
3671 }
3672
3673
3674 /*
3675  * ALTER TABLE DROP COLUMN
3676  *
3677  * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
3678  * because we have to decide at runtime whether to recurse or not depending
3679  * on whether attinhcount goes to zero or not.  (We can't check this in a
3680  * static pre-pass because it won't handle multiple inheritance situations
3681  * correctly.)  Since DROP COLUMN doesn't need to create any work queue
3682  * entries for Phase 3, it's okay to recurse internally in this routine
3683  * without considering the work queue.
3684  */
3685 static void
3686 ATExecDropColumn(Relation rel, const char *colName,
3687                                  DropBehavior behavior,
3688                                  bool recurse, bool recursing)
3689 {
3690         HeapTuple       tuple;
3691         Form_pg_attribute targetatt;
3692         AttrNumber      attnum;
3693         List       *children;
3694         ObjectAddress object;
3695
3696         /* At top level, permission check was done in ATPrepCmd, else do it */
3697         if (recursing)
3698                 ATSimplePermissions(rel, false);
3699
3700         /*
3701          * get the number of the attribute
3702          */
3703         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
3704         if (!HeapTupleIsValid(tuple))
3705                 ereport(ERROR,
3706                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
3707                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
3708                                                 colName, RelationGetRelationName(rel))));
3709         targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
3710
3711         attnum = targetatt->attnum;
3712
3713         /* Can't drop a system attribute, except OID */
3714         if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
3715                 ereport(ERROR,
3716                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3717                                  errmsg("cannot drop system column \"%s\"",
3718                                                 colName)));
3719
3720         /* Don't drop inherited columns */
3721         if (targetatt->attinhcount > 0 && !recursing)
3722                 ereport(ERROR,
3723                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3724                                  errmsg("cannot drop inherited column \"%s\"",
3725                                                 colName)));
3726
3727         ReleaseSysCache(tuple);
3728
3729         /*
3730          * Propagate to children as appropriate.  Unlike most other ALTER
3731          * routines, we have to do this one level of recursion at a time; we can't
3732          * use find_all_inheritors to do it in one pass.
3733          */
3734         children = find_inheritance_children(RelationGetRelid(rel));
3735
3736         if (children)
3737         {
3738                 Relation        attr_rel;
3739                 ListCell   *child;
3740
3741                 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3742                 foreach(child, children)
3743                 {
3744                         Oid                     childrelid = lfirst_oid(child);
3745                         Relation        childrel;
3746                         Form_pg_attribute childatt;
3747
3748                         childrel = heap_open(childrelid, AccessExclusiveLock);
3749
3750                         tuple = SearchSysCacheCopyAttName(childrelid, colName);
3751                         if (!HeapTupleIsValid(tuple))           /* shouldn't happen */
3752                                 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
3753                                          colName, childrelid);
3754                         childatt = (Form_pg_attribute) GETSTRUCT(tuple);
3755
3756                         if (childatt->attinhcount <= 0)         /* shouldn't happen */
3757                                 elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
3758                                          childrelid, colName);
3759
3760                         if (recurse)
3761                         {
3762                                 /*
3763                                  * If the child column has other definition sources, just
3764                                  * decrement its inheritance count; if not, recurse to delete
3765                                  * it.
3766                                  */
3767                                 if (childatt->attinhcount == 1 && !childatt->attislocal)
3768                                 {
3769                                         /* Time to delete this child column, too */
3770                                         ATExecDropColumn(childrel, colName, behavior, true, true);
3771                                 }
3772                                 else
3773                                 {
3774                                         /* Child column must survive my deletion */
3775                                         childatt->attinhcount--;
3776
3777                                         simple_heap_update(attr_rel, &tuple->t_self, tuple);
3778
3779                                         /* keep the system catalog indexes current */
3780                                         CatalogUpdateIndexes(attr_rel, tuple);
3781
3782                                         /* Make update visible */
3783                                         CommandCounterIncrement();
3784                                 }
3785                         }
3786                         else
3787                         {
3788                                 /*
3789                                  * If we were told to drop ONLY in this table (no recursion),
3790                                  * we need to mark the inheritors' attribute as locally
3791                                  * defined rather than inherited.
3792                                  */
3793                                 childatt->attinhcount--;
3794                                 childatt->attislocal = true;
3795
3796                                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3797
3798                                 /* keep the system catalog indexes current */
3799                                 CatalogUpdateIndexes(attr_rel, tuple);
3800
3801                                 /* Make update visible */
3802                                 CommandCounterIncrement();
3803                         }
3804
3805                         heap_freetuple(tuple);
3806
3807                         heap_close(childrel, NoLock);
3808                 }
3809                 heap_close(attr_rel, RowExclusiveLock);
3810         }
3811
3812         /*
3813          * Perform the actual column deletion
3814          */
3815         object.classId = RelationRelationId;
3816         object.objectId = RelationGetRelid(rel);
3817         object.objectSubId = attnum;
3818
3819         performDeletion(&object, behavior);
3820
3821         /*
3822          * If we dropped the OID column, must adjust pg_class.relhasoids
3823          */
3824         if (attnum == ObjectIdAttributeNumber)
3825         {
3826                 Relation        class_rel;
3827                 Form_pg_class tuple_class;
3828
3829                 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
3830
3831                 tuple = SearchSysCacheCopy(RELOID,
3832                                                                    ObjectIdGetDatum(RelationGetRelid(rel)),
3833                                                                    0, 0, 0);
3834                 if (!HeapTupleIsValid(tuple))
3835                         elog(ERROR, "cache lookup failed for relation %u",
3836                                  RelationGetRelid(rel));
3837                 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
3838
3839                 tuple_class->relhasoids = false;
3840                 simple_heap_update(class_rel, &tuple->t_self, tuple);
3841
3842                 /* Keep the catalog indexes up to date */
3843                 CatalogUpdateIndexes(class_rel, tuple);
3844
3845                 heap_close(class_rel, RowExclusiveLock);
3846         }
3847 }
3848
3849 /*
3850  * ALTER TABLE ADD INDEX
3851  *
3852  * There is no such command in the grammar, but the parser converts UNIQUE
3853  * and PRIMARY KEY constraints into AT_AddIndex subcommands.  This lets us
3854  * schedule creation of the index at the appropriate time during ALTER.
3855  */
3856 static void
3857 ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
3858                            IndexStmt *stmt, bool is_rebuild)
3859 {
3860         bool            check_rights;
3861         bool            skip_build;
3862         bool            quiet;
3863
3864         Assert(IsA(stmt, IndexStmt));
3865
3866         /* suppress schema rights check when rebuilding existing index */
3867         check_rights = !is_rebuild;
3868         /* skip index build if phase 3 will have to rewrite table anyway */
3869         skip_build = (tab->newvals != NIL);
3870         /* suppress notices when rebuilding existing index */
3871         quiet = is_rebuild;
3872
3873         DefineIndex(stmt->relation, /* relation */
3874                                 stmt->idxname,  /* index name */
3875                                 InvalidOid,             /* no predefined OID */
3876                                 stmt->accessMethod,             /* am name */
3877                                 stmt->tableSpace,
3878                                 stmt->indexParams,              /* parameters */
3879                                 (Expr *) stmt->whereClause,
3880                                 stmt->rangetable,
3881                                 stmt->options,
3882                                 stmt->unique,
3883                                 stmt->primary,
3884                                 stmt->isconstraint,
3885                                 true,                   /* is_alter_table */
3886                                 check_rights,
3887                                 skip_build,
3888                                 quiet,
3889                                 false);
3890 }
3891
3892 /*
3893  * ALTER TABLE ADD CONSTRAINT
3894  */
3895 static void
3896 ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
3897 {
3898         switch (nodeTag(newConstraint))
3899         {
3900                 case T_Constraint:
3901                         {
3902                                 Constraint *constr = (Constraint *) newConstraint;
3903
3904                                 /*
3905                                  * Currently, we only expect to see CONSTR_CHECK nodes
3906                                  * arriving here (see the preprocessing done in
3907                                  * parser/analyze.c).  Use a switch anyway to make it easier
3908                                  * to add more code later.
3909                                  */
3910                                 switch (constr->contype)
3911                                 {
3912                                         case CONSTR_CHECK:
3913                                                 {
3914                                                         List       *newcons;
3915                                                         ListCell   *lcon;
3916
3917                                                         /*
3918                                                          * Call AddRelationRawConstraints to do the work.
3919                                                          * It returns a list of cooked constraints.
3920                                                          */
3921                                                         newcons = AddRelationRawConstraints(rel, NIL,
3922                                                                                                                  list_make1(constr));
3923                                                         /* Add each constraint to Phase 3's queue */
3924                                                         foreach(lcon, newcons)
3925                                                         {
3926                                                                 CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
3927                                                                 NewConstraint *newcon;
3928
3929                                                                 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
3930                                                                 newcon->name = ccon->name;
3931                                                                 newcon->contype = ccon->contype;
3932                                                                 /* ExecQual wants implicit-AND format */
3933                                                                 newcon->qual = (Node *)
3934                                                                         make_ands_implicit((Expr *) ccon->expr);
3935
3936                                                                 tab->constraints = lappend(tab->constraints,
3937                                                                                                                    newcon);
3938                                                         }
3939                                                         break;
3940                                                 }
3941                                         default:
3942                                                 elog(ERROR, "unrecognized constraint type: %d",
3943                                                          (int) constr->contype);
3944                                 }
3945                                 break;
3946                         }
3947                 case T_FkConstraint:
3948                         {
3949                                 FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
3950
3951                                 /*
3952                                  * Assign or validate constraint name
3953                                  */
3954                                 if (fkconstraint->constr_name)
3955                                 {
3956                                         if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
3957                                                                                          RelationGetRelid(rel),
3958                                                                                          RelationGetNamespace(rel),
3959                                                                                          fkconstraint->constr_name))
3960                                                 ereport(ERROR,
3961                                                                 (errcode(ERRCODE_DUPLICATE_OBJECT),
3962                                                                  errmsg("constraint \"%s\" for relation \"%s\" already exists",
3963                                                                                 fkconstraint->constr_name,
3964                                                                                 RelationGetRelationName(rel))));
3965                                 }
3966                                 else
3967                                         fkconstraint->constr_name =
3968                                                 ChooseConstraintName(RelationGetRelationName(rel),
3969                                                                         strVal(linitial(fkconstraint->fk_attrs)),
3970                                                                                          "fkey",
3971                                                                                          RelationGetNamespace(rel),
3972                                                                                          NIL);
3973
3974                                 ATAddForeignKeyConstraint(tab, rel, fkconstraint);
3975
3976                                 break;
3977                         }
3978                 default:
3979                         elog(ERROR, "unrecognized node type: %d",
3980                                  (int) nodeTag(newConstraint));
3981         }
3982 }
3983
3984 /*
3985  * Add a foreign-key constraint to a single table
3986  *
3987  * Subroutine for ATExecAddConstraint.  Must already hold exclusive
3988  * lock on the rel, and have done appropriate validity/permissions checks
3989  * for it.
3990  */
3991 static void
3992 ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
3993                                                   FkConstraint *fkconstraint)
3994 {
3995         Relation        pkrel;
3996         AclResult       aclresult;
3997         int16           pkattnum[INDEX_MAX_KEYS];
3998         int16           fkattnum[INDEX_MAX_KEYS];
3999         Oid                     pktypoid[INDEX_MAX_KEYS];
4000         Oid                     fktypoid[INDEX_MAX_KEYS];
4001         Oid                     opclasses[INDEX_MAX_KEYS];
4002         int                     i;
4003         int                     numfks,
4004                                 numpks;
4005         Oid                     indexOid;
4006         Oid                     constrOid;
4007
4008         /*
4009          * Grab an exclusive lock on the pk table, so that someone doesn't delete
4010          * rows out from under us. (Although a lesser lock would do for that
4011          * purpose, we'll need exclusive lock anyway to add triggers to the pk
4012          * table; trying to start with a lesser lock will just create a risk of
4013          * deadlock.)
4014          */
4015         pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
4016
4017         /*
4018          * Validity and permissions checks
4019          *
4020          * Note: REFERENCES permissions checks are redundant with CREATE TRIGGER,
4021          * but we may as well error out sooner instead of later.
4022          */
4023         if (pkrel->rd_rel->relkind != RELKIND_RELATION)
4024                 ereport(ERROR,
4025                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4026                                  errmsg("referenced relation \"%s\" is not a table",
4027                                                 RelationGetRelationName(pkrel))));
4028
4029         aclresult = pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(),
4030                                                                   ACL_REFERENCES);
4031         if (aclresult != ACLCHECK_OK)
4032                 aclcheck_error(aclresult, ACL_KIND_CLASS,
4033                                            RelationGetRelationName(pkrel));
4034
4035         if (!allowSystemTableMods && IsSystemRelation(pkrel))
4036                 ereport(ERROR,
4037                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4038                                  errmsg("permission denied: \"%s\" is a system catalog",
4039                                                 RelationGetRelationName(pkrel))));
4040
4041         aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
4042                                                                   ACL_REFERENCES);
4043         if (aclresult != ACLCHECK_OK)
4044                 aclcheck_error(aclresult, ACL_KIND_CLASS,
4045                                            RelationGetRelationName(rel));
4046
4047         /*
4048          * Disallow reference from permanent table to temp table or vice versa.
4049          * (The ban on perm->temp is for fairly obvious reasons.  The ban on
4050          * temp->perm is because other backends might need to run the RI triggers
4051          * on the perm table, but they can't reliably see tuples the owning
4052          * backend has created in the temp table, because non-shared buffers are
4053          * used for temp tables.)
4054          */
4055         if (isTempNamespace(RelationGetNamespace(pkrel)))
4056         {
4057                 if (!isTempNamespace(RelationGetNamespace(rel)))
4058                         ereport(ERROR,
4059                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4060                                          errmsg("cannot reference temporary table from permanent table constraint")));
4061         }
4062         else
4063         {
4064                 if (isTempNamespace(RelationGetNamespace(rel)))
4065                         ereport(ERROR,
4066                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4067                                          errmsg("cannot reference permanent table from temporary table constraint")));
4068         }
4069
4070         /*
4071          * Look up the referencing attributes to make sure they exist, and record
4072          * their attnums and type OIDs.
4073          */
4074         MemSet(pkattnum, 0, sizeof(pkattnum));
4075         MemSet(fkattnum, 0, sizeof(fkattnum));
4076         MemSet(pktypoid, 0, sizeof(pktypoid));
4077         MemSet(fktypoid, 0, sizeof(fktypoid));
4078         MemSet(opclasses, 0, sizeof(opclasses));
4079
4080         numfks = transformColumnNameList(RelationGetRelid(rel),
4081                                                                          fkconstraint->fk_attrs,
4082                                                                          fkattnum, fktypoid);
4083
4084         /*
4085          * If the attribute list for the referenced table was omitted, lookup the
4086          * definition of the primary key and use it.  Otherwise, validate the
4087          * supplied attribute list.  In either case, discover the index OID and
4088          * index opclasses, and the attnums and type OIDs of the attributes.
4089          */
4090         if (fkconstraint->pk_attrs == NIL)
4091         {
4092                 numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
4093                                                                                         &fkconstraint->pk_attrs,
4094                                                                                         pkattnum, pktypoid,
4095                                                                                         opclasses);
4096         }
4097         else
4098         {
4099                 numpks = transformColumnNameList(RelationGetRelid(pkrel),
4100                                                                                  fkconstraint->pk_attrs,
4101                                                                                  pkattnum, pktypoid);
4102                 /* Look for an index matching the column list */
4103                 indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
4104                                                                                    opclasses);
4105         }
4106
4107         /* Be sure referencing and referenced column types are comparable */
4108         if (numfks != numpks)
4109                 ereport(ERROR,
4110                                 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
4111                                  errmsg("number of referencing and referenced columns for foreign key disagree")));
4112
4113         for (i = 0; i < numpks; i++)
4114         {
4115                 /*
4116                  * pktypoid[i] is the primary key table's i'th key's type fktypoid[i]
4117                  * is the foreign key table's i'th key's type
4118                  *
4119                  * Note that we look for an operator with the PK type on the left;
4120                  * when the types are different this is critical because the PK index
4121                  * will need operators with the indexkey on the left. (Ordinarily both
4122                  * commutator operators will exist if either does, but we won't get
4123                  * the right answer from the test below on opclass membership unless
4124                  * we select the proper operator.)
4125                  */
4126                 Operator        o = oper(NULL, list_make1(makeString("=")),
4127                                                          pktypoid[i], fktypoid[i],
4128                                                          true, -1);
4129
4130                 if (o == NULL)
4131                         ereport(ERROR,
4132                                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
4133                                          errmsg("foreign key constraint \"%s\" "
4134                                                         "cannot be implemented",
4135                                                         fkconstraint->constr_name),
4136                                          errdetail("Key columns \"%s\" and \"%s\" "
4137                                                            "are of incompatible types: %s and %s.",
4138                                                            strVal(list_nth(fkconstraint->fk_attrs, i)),
4139                                                            strVal(list_nth(fkconstraint->pk_attrs, i)),
4140                                                            format_type_be(fktypoid[i]),
4141                                                            format_type_be(pktypoid[i]))));
4142
4143                 /*
4144                  * Check that the found operator is compatible with the PK index, and
4145                  * generate a warning if not, since otherwise costly seqscans will be
4146                  * incurred to check FK validity.
4147                  */
4148                 if (!op_in_opfamily(oprid(o), get_opclass_family(opclasses[i])))
4149                         ereport(WARNING,
4150                                         (errmsg("foreign key constraint \"%s\" "
4151                                                         "will require costly sequential scans",
4152                                                         fkconstraint->constr_name),
4153                                          errdetail("Key columns \"%s\" and \"%s\" "
4154                                                            "are of different types: %s and %s.",
4155                                                            strVal(list_nth(fkconstraint->fk_attrs, i)),
4156                                                            strVal(list_nth(fkconstraint->pk_attrs, i)),
4157                                                            format_type_be(fktypoid[i]),
4158                                                            format_type_be(pktypoid[i]))));
4159
4160                 ReleaseSysCache(o);
4161         }
4162
4163         /*
4164          * Tell Phase 3 to check that the constraint is satisfied by existing rows
4165          * (we can skip this during table creation).
4166          */
4167         if (!fkconstraint->skip_validation)
4168         {
4169                 NewConstraint *newcon;
4170
4171                 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
4172                 newcon->name = fkconstraint->constr_name;
4173                 newcon->contype = CONSTR_FOREIGN;
4174                 newcon->refrelid = RelationGetRelid(pkrel);
4175                 newcon->qual = (Node *) fkconstraint;
4176
4177                 tab->constraints = lappend(tab->constraints, newcon);
4178         }
4179
4180         /*
4181          * Record the FK constraint in pg_constraint.
4182          */
4183         constrOid = CreateConstraintEntry(fkconstraint->constr_name,
4184                                                                           RelationGetNamespace(rel),
4185                                                                           CONSTRAINT_FOREIGN,
4186                                                                           fkconstraint->deferrable,
4187                                                                           fkconstraint->initdeferred,
4188                                                                           RelationGetRelid(rel),
4189                                                                           fkattnum,
4190                                                                           numfks,
4191                                                                           InvalidOid,           /* not a domain
4192                                                                                                                  * constraint */
4193                                                                           RelationGetRelid(pkrel),
4194                                                                           pkattnum,
4195                                                                           numpks,
4196                                                                           fkconstraint->fk_upd_action,
4197                                                                           fkconstraint->fk_del_action,
4198                                                                           fkconstraint->fk_matchtype,
4199                                                                           indexOid,
4200                                                                           NULL,         /* no check constraint */
4201                                                                           NULL,
4202                                                                           NULL);
4203
4204         /*
4205          * Create the triggers that will enforce the constraint.
4206          */
4207         createForeignKeyTriggers(rel, fkconstraint, constrOid);
4208
4209         /*
4210          * Close pk table, but keep lock until we've committed.
4211          */
4212         heap_close(pkrel, NoLock);
4213 }
4214
4215
4216 /*
4217  * transformColumnNameList - transform list of column names
4218  *
4219  * Lookup each name and return its attnum and type OID
4220  */
4221 static int
4222 transformColumnNameList(Oid relId, List *colList,
4223                                                 int16 *attnums, Oid *atttypids)
4224 {
4225         ListCell   *l;
4226         int                     attnum;
4227
4228         attnum = 0;
4229         foreach(l, colList)
4230         {
4231                 char       *attname = strVal(lfirst(l));
4232                 HeapTuple       atttuple;
4233
4234                 atttuple = SearchSysCacheAttName(relId, attname);
4235                 if (!HeapTupleIsValid(atttuple))
4236                         ereport(ERROR,
4237                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
4238                                          errmsg("column \"%s\" referenced in foreign key constraint does not exist",
4239                                                         attname)));
4240                 if (attnum >= INDEX_MAX_KEYS)
4241                         ereport(ERROR,
4242                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
4243                                          errmsg("cannot have more than %d keys in a foreign key",
4244                                                         INDEX_MAX_KEYS)));
4245                 attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
4246                 atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
4247                 ReleaseSysCache(atttuple);
4248                 attnum++;
4249         }
4250
4251         return attnum;
4252 }
4253
4254 /*
4255  * transformFkeyGetPrimaryKey -
4256  *
4257  *      Look up the names, attnums, and types of the primary key attributes
4258  *      for the pkrel.  Also return the index OID and index opclasses of the
4259  *      index supporting the primary key.
4260  *
4261  *      All parameters except pkrel are output parameters.      Also, the function
4262  *      return value is the number of attributes in the primary key.
4263  *
4264  *      Used when the column list in the REFERENCES specification is omitted.
4265  */
4266 static int
4267 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
4268                                                    List **attnamelist,
4269                                                    int16 *attnums, Oid *atttypids,
4270                                                    Oid *opclasses)
4271 {
4272         List       *indexoidlist;
4273         ListCell   *indexoidscan;
4274         HeapTuple       indexTuple = NULL;
4275         Form_pg_index indexStruct = NULL;
4276         Datum           indclassDatum;
4277         bool            isnull;
4278         oidvector  *indclass;
4279         int                     i;
4280
4281         /*
4282          * Get the list of index OIDs for the table from the relcache, and look up
4283          * each one in the pg_index syscache until we find one marked primary key
4284          * (hopefully there isn't more than one such).
4285          */
4286         *indexOid = InvalidOid;
4287
4288         indexoidlist = RelationGetIndexList(pkrel);
4289
4290         foreach(indexoidscan, indexoidlist)
4291         {
4292                 Oid                     indexoid = lfirst_oid(indexoidscan);
4293
4294                 indexTuple = SearchSysCache(INDEXRELID,
4295                                                                         ObjectIdGetDatum(indexoid),
4296                                                                         0, 0, 0);
4297                 if (!HeapTupleIsValid(indexTuple))
4298                         elog(ERROR, "cache lookup failed for index %u", indexoid);
4299                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4300                 if (indexStruct->indisprimary)
4301                 {
4302                         *indexOid = indexoid;
4303                         break;
4304                 }
4305                 ReleaseSysCache(indexTuple);
4306         }
4307
4308         list_free(indexoidlist);
4309
4310         /*
4311          * Check that we found it
4312          */
4313         if (!OidIsValid(*indexOid))
4314                 ereport(ERROR,
4315                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
4316                                  errmsg("there is no primary key for referenced table \"%s\"",
4317                                                 RelationGetRelationName(pkrel))));
4318
4319         /* Must get indclass the hard way */
4320         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
4321                                                                         Anum_pg_index_indclass, &isnull);
4322         Assert(!isnull);
4323         indclass = (oidvector *) DatumGetPointer(indclassDatum);
4324
4325         /*
4326          * Now build the list of PK attributes from the indkey definition (we
4327          * assume a primary key cannot have expressional elements)
4328          */
4329         *attnamelist = NIL;
4330         for (i = 0; i < indexStruct->indnatts; i++)
4331         {
4332                 int                     pkattno = indexStruct->indkey.values[i];
4333
4334                 attnums[i] = pkattno;
4335                 atttypids[i] = attnumTypeId(pkrel, pkattno);
4336                 opclasses[i] = indclass->values[i];
4337                 *attnamelist = lappend(*attnamelist,
4338                            makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
4339         }
4340
4341         ReleaseSysCache(indexTuple);
4342
4343         return i;
4344 }
4345
4346 /*
4347  * transformFkeyCheckAttrs -
4348  *
4349  *      Make sure that the attributes of a referenced table belong to a unique
4350  *      (or primary key) constraint.  Return the OID of the index supporting
4351  *      the constraint, as well as the opclasses associated with the index
4352  *      columns.
4353  */
4354 static Oid
4355 transformFkeyCheckAttrs(Relation pkrel,
4356                                                 int numattrs, int16 *attnums,
4357                                                 Oid *opclasses) /* output parameter */
4358 {
4359         Oid                     indexoid = InvalidOid;
4360         bool            found = false;
4361         List       *indexoidlist;
4362         ListCell   *indexoidscan;
4363
4364         /*
4365          * Get the list of index OIDs for the table from the relcache, and look up
4366          * each one in the pg_index syscache, and match unique indexes to the list
4367          * of attnums we are given.
4368          */
4369         indexoidlist = RelationGetIndexList(pkrel);
4370
4371         foreach(indexoidscan, indexoidlist)
4372         {
4373                 HeapTuple       indexTuple;
4374                 Form_pg_index indexStruct;
4375                 int                     i,
4376                                         j;
4377
4378                 indexoid = lfirst_oid(indexoidscan);
4379                 indexTuple = SearchSysCache(INDEXRELID,
4380                                                                         ObjectIdGetDatum(indexoid),
4381                                                                         0, 0, 0);
4382                 if (!HeapTupleIsValid(indexTuple))
4383                         elog(ERROR, "cache lookup failed for index %u", indexoid);
4384                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4385
4386                 /*
4387                  * Must have the right number of columns; must be unique and not a
4388                  * partial index; forget it if there are any expressions, too
4389                  */
4390                 if (indexStruct->indnatts == numattrs &&
4391                         indexStruct->indisunique &&
4392                         heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
4393                         heap_attisnull(indexTuple, Anum_pg_index_indexprs))
4394                 {
4395                         /* Must get indclass the hard way */
4396                         Datum           indclassDatum;
4397                         bool            isnull;
4398                         oidvector  *indclass;
4399
4400                         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
4401                                                                                         Anum_pg_index_indclass, &isnull);
4402                         Assert(!isnull);
4403                         indclass = (oidvector *) DatumGetPointer(indclassDatum);
4404
4405                         /*
4406                          * The given attnum list may match the index columns in any order.
4407                          * Check that each list is a subset of the other.
4408                          */
4409                         for (i = 0; i < numattrs; i++)
4410                         {
4411                                 found = false;
4412                                 for (j = 0; j < numattrs; j++)
4413                                 {
4414                                         if (attnums[i] == indexStruct->indkey.values[j])
4415                                         {
4416                                                 found = true;
4417                                                 break;
4418                                         }
4419                                 }
4420                                 if (!found)
4421                                         break;
4422                         }
4423                         if (found)
4424                         {
4425                                 for (i = 0; i < numattrs; i++)
4426                                 {
4427                                         found = false;
4428                                         for (j = 0; j < numattrs; j++)
4429                                         {
4430                                                 if (attnums[j] == indexStruct->indkey.values[i])
4431                                                 {
4432                                                         opclasses[j] = indclass->values[i];
4433                                                         found = true;
4434                                                         break;
4435                                                 }
4436                                         }
4437                                         if (!found)
4438                                                 break;
4439                                 }
4440                         }
4441                 }
4442                 ReleaseSysCache(indexTuple);
4443                 if (found)
4444                         break;
4445         }
4446
4447         if (!found)
4448                 ereport(ERROR,
4449                                 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
4450                                  errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
4451                                                 RelationGetRelationName(pkrel))));
4452
4453         list_free(indexoidlist);
4454
4455         return indexoid;
4456 }
4457
4458 /*
4459  * Scan the existing rows in a table to verify they meet a proposed FK
4460  * constraint.
4461  *
4462  * Caller must have opened and locked both relations.
4463  */
4464 static void
4465 validateForeignKeyConstraint(FkConstraint *fkconstraint,
4466                                                          Relation rel,
4467                                                          Relation pkrel)
4468 {
4469         HeapScanDesc scan;
4470         HeapTuple       tuple;
4471         Trigger         trig;
4472         ListCell   *list;
4473         int                     count;
4474
4475         /*
4476          * See if we can do it with a single LEFT JOIN query.  A FALSE result
4477          * indicates we must proceed with the fire-the-trigger method.
4478          */
4479         if (RI_Initial_Check(fkconstraint, rel, pkrel))
4480                 return;
4481
4482         /*
4483          * Scan through each tuple, calling RI_FKey_check_ins (insert trigger) as
4484          * if that tuple had just been inserted.  If any of those fail, it should
4485          * ereport(ERROR) and that's that.
4486          */
4487         MemSet(&trig, 0, sizeof(trig));
4488         trig.tgoid = InvalidOid;
4489         trig.tgname = fkconstraint->constr_name;
4490         trig.tgenabled = TRUE;
4491         trig.tgisconstraint = TRUE;
4492         trig.tgconstrrelid = RelationGetRelid(pkrel);
4493         trig.tgdeferrable = FALSE;
4494         trig.tginitdeferred = FALSE;
4495
4496         trig.tgargs = (char **) palloc(sizeof(char *) *
4497                                                                    (4 + list_length(fkconstraint->fk_attrs)
4498                                                                         + list_length(fkconstraint->pk_attrs)));
4499
4500         trig.tgargs[0] = trig.tgname;
4501         trig.tgargs[1] = RelationGetRelationName(rel);
4502         trig.tgargs[2] = RelationGetRelationName(pkrel);
4503         trig.tgargs[3] = fkMatchTypeToString(fkconstraint->fk_matchtype);
4504         count = 4;
4505         foreach(list, fkconstraint->fk_attrs)
4506         {
4507                 char       *fk_at = strVal(lfirst(list));
4508
4509                 trig.tgargs[count] = fk_at;
4510                 count += 2;
4511         }
4512         count = 5;
4513         foreach(list, fkconstraint->pk_attrs)
4514         {
4515                 char       *pk_at = strVal(lfirst(list));
4516
4517                 trig.tgargs[count] = pk_at;
4518                 count += 2;
4519         }
4520         trig.tgnargs = count - 1;
4521
4522         scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
4523
4524         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4525         {
4526                 FunctionCallInfoData fcinfo;
4527                 TriggerData trigdata;
4528
4529                 /*
4530                  * Make a call to the trigger function
4531                  *
4532                  * No parameters are passed, but we do set a context
4533                  */
4534                 MemSet(&fcinfo, 0, sizeof(fcinfo));
4535
4536                 /*
4537                  * We assume RI_FKey_check_ins won't look at flinfo...
4538                  */
4539                 trigdata.type = T_TriggerData;
4540                 trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
4541                 trigdata.tg_relation = rel;
4542                 trigdata.tg_trigtuple = tuple;
4543                 trigdata.tg_newtuple = NULL;
4544                 trigdata.tg_trigger = &trig;
4545                 trigdata.tg_trigtuplebuf = scan->rs_cbuf;
4546                 trigdata.tg_newtuplebuf = InvalidBuffer;
4547
4548                 fcinfo.context = (Node *) &trigdata;
4549
4550                 RI_FKey_check_ins(&fcinfo);
4551         }
4552
4553         heap_endscan(scan);
4554
4555         pfree(trig.tgargs);
4556 }
4557
4558 static void
4559 CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
4560                                          ObjectAddress *constrobj, ObjectAddress *trigobj,
4561                                          bool on_insert)
4562 {
4563         CreateTrigStmt *fk_trigger;
4564         ListCell   *fk_attr;
4565         ListCell   *pk_attr;
4566
4567         fk_trigger = makeNode(CreateTrigStmt);
4568         fk_trigger->trigname = fkconstraint->constr_name;
4569         fk_trigger->relation = myRel;
4570         fk_trigger->before = false;
4571         fk_trigger->row = true;
4572
4573         /* Either ON INSERT or ON UPDATE */
4574         if (on_insert)
4575         {
4576                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
4577                 fk_trigger->actions[0] = 'i';
4578         }
4579         else
4580         {
4581                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
4582                 fk_trigger->actions[0] = 'u';
4583         }
4584         fk_trigger->actions[1] = '\0';
4585
4586         fk_trigger->isconstraint = true;
4587         fk_trigger->deferrable = fkconstraint->deferrable;
4588         fk_trigger->initdeferred = fkconstraint->initdeferred;
4589         fk_trigger->constrrel = fkconstraint->pktable;
4590
4591         fk_trigger->args = NIL;
4592         fk_trigger->args = lappend(fk_trigger->args,
4593                                                            makeString(fkconstraint->constr_name));
4594         fk_trigger->args = lappend(fk_trigger->args,
4595                                                            makeString(myRel->relname));
4596         fk_trigger->args = lappend(fk_trigger->args,
4597                                                            makeString(fkconstraint->pktable->relname));
4598         fk_trigger->args = lappend(fk_trigger->args,
4599                                 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4600         if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
4601                 ereport(ERROR,
4602                                 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
4603                                  errmsg("number of referencing and referenced columns for foreign key disagree")));
4604
4605         forboth(fk_attr, fkconstraint->fk_attrs,
4606                         pk_attr, fkconstraint->pk_attrs)
4607         {
4608                 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4609                 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4610         }
4611
4612         trigobj->objectId = CreateTrigger(fk_trigger, true);
4613
4614         /* Register dependency from trigger to constraint */
4615         recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL);
4616
4617         /* Make changes-so-far visible */
4618         CommandCounterIncrement();
4619 }
4620
4621 /*
4622  * Create the triggers that implement an FK constraint.
4623  */
4624 static void
4625 createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
4626                                                  Oid constrOid)
4627 {
4628         RangeVar   *myRel;
4629         CreateTrigStmt *fk_trigger;
4630         ListCell   *fk_attr;
4631         ListCell   *pk_attr;
4632         ObjectAddress trigobj,
4633                                 constrobj;
4634
4635         /*
4636          * Reconstruct a RangeVar for my relation (not passed in, unfortunately).
4637          */
4638         myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
4639                                                  pstrdup(RelationGetRelationName(rel)));
4640
4641         /*
4642          * Preset objectAddress fields
4643          */
4644         constrobj.classId = ConstraintRelationId;
4645         constrobj.objectId = constrOid;
4646         constrobj.objectSubId = 0;
4647         trigobj.classId = TriggerRelationId;
4648         trigobj.objectSubId = 0;
4649
4650         /* Make changes-so-far visible */
4651         CommandCounterIncrement();
4652
4653         /*
4654          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK
4655          * action for both INSERTs and UPDATEs on the referencing table.
4656          */
4657         CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, true);
4658         CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, false);
4659
4660         /*
4661          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
4662          * DELETE action on the referenced table.
4663          */
4664         fk_trigger = makeNode(CreateTrigStmt);
4665         fk_trigger->trigname = fkconstraint->constr_name;
4666         fk_trigger->relation = fkconstraint->pktable;
4667         fk_trigger->before = false;
4668         fk_trigger->row = true;
4669         fk_trigger->actions[0] = 'd';
4670         fk_trigger->actions[1] = '\0';
4671
4672         fk_trigger->isconstraint = true;
4673         fk_trigger->constrrel = myRel;
4674         switch (fkconstraint->fk_del_action)
4675         {
4676                 case FKCONSTR_ACTION_NOACTION:
4677                         fk_trigger->deferrable = fkconstraint->deferrable;
4678                         fk_trigger->initdeferred = fkconstraint->initdeferred;
4679                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
4680                         break;
4681                 case FKCONSTR_ACTION_RESTRICT:
4682                         fk_trigger->deferrable = false;
4683                         fk_trigger->initdeferred = false;
4684                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
4685                         break;
4686                 case FKCONSTR_ACTION_CASCADE:
4687                         fk_trigger->deferrable = false;
4688                         fk_trigger->initdeferred = false;
4689                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
4690                         break;
4691                 case FKCONSTR_ACTION_SETNULL:
4692                         fk_trigger->deferrable = false;
4693                         fk_trigger->initdeferred = false;
4694                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
4695                         break;
4696                 case FKCONSTR_ACTION_SETDEFAULT:
4697                         fk_trigger->deferrable = false;
4698                         fk_trigger->initdeferred = false;
4699                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
4700                         break;
4701                 default:
4702                         elog(ERROR, "unrecognized FK action type: %d",
4703                                  (int) fkconstraint->fk_del_action);
4704                         break;
4705         }
4706
4707         fk_trigger->args = NIL;
4708         fk_trigger->args = lappend(fk_trigger->args,
4709                                                            makeString(fkconstraint->constr_name));
4710         fk_trigger->args = lappend(fk_trigger->args,
4711                                                            makeString(myRel->relname));
4712         fk_trigger->args = lappend(fk_trigger->args,
4713                                                            makeString(fkconstraint->pktable->relname));
4714         fk_trigger->args = lappend(fk_trigger->args,
4715                                 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4716         forboth(fk_attr, fkconstraint->fk_attrs,
4717                         pk_attr, fkconstraint->pk_attrs)
4718         {
4719                 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4720                 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4721         }
4722
4723         trigobj.objectId = CreateTrigger(fk_trigger, true);
4724
4725         /* Register dependency from trigger to constraint */
4726         recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
4727
4728         /* Make changes-so-far visible */
4729         CommandCounterIncrement();
4730
4731         /*
4732          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
4733          * UPDATE action on the referenced table.
4734          */
4735         fk_trigger = makeNode(CreateTrigStmt);
4736         fk_trigger->trigname = fkconstraint->constr_name;
4737         fk_trigger->relation = fkconstraint->pktable;
4738         fk_trigger->before = false;
4739         fk_trigger->row = true;
4740         fk_trigger->actions[0] = 'u';
4741         fk_trigger->actions[1] = '\0';
4742         fk_trigger->isconstraint = true;
4743         fk_trigger->constrrel = myRel;
4744         switch (fkconstraint->fk_upd_action)
4745         {
4746                 case FKCONSTR_ACTION_NOACTION:
4747                         fk_trigger->deferrable = fkconstraint->deferrable;
4748                         fk_trigger->initdeferred = fkconstraint->initdeferred;
4749                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
4750                         break;
4751                 case FKCONSTR_ACTION_RESTRICT:
4752                         fk_trigger->deferrable = false;
4753                         fk_trigger->initdeferred = false;
4754                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
4755                         break;
4756                 case FKCONSTR_ACTION_CASCADE:
4757                         fk_trigger->deferrable = false;
4758                         fk_trigger->initdeferred = false;
4759                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
4760                         break;
4761                 case FKCONSTR_ACTION_SETNULL:
4762                         fk_trigger->deferrable = false;
4763                         fk_trigger->initdeferred = false;
4764                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
4765                         break;
4766                 case FKCONSTR_ACTION_SETDEFAULT:
4767                         fk_trigger->deferrable = false;
4768                         fk_trigger->initdeferred = false;
4769                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
4770                         break;
4771                 default:
4772                         elog(ERROR, "unrecognized FK action type: %d",
4773                                  (int) fkconstraint->fk_upd_action);
4774                         break;
4775         }
4776
4777         fk_trigger->args = NIL;
4778         fk_trigger->args = lappend(fk_trigger->args,
4779                                                            makeString(fkconstraint->constr_name));
4780         fk_trigger->args = lappend(fk_trigger->args,
4781                                                            makeString(myRel->relname));
4782         fk_trigger->args = lappend(fk_trigger->args,
4783                                                            makeString(fkconstraint->pktable->relname));
4784         fk_trigger->args = lappend(fk_trigger->args,
4785                                 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4786         forboth(fk_attr, fkconstraint->fk_attrs,
4787                         pk_attr, fkconstraint->pk_attrs)
4788         {
4789                 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4790                 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4791         }
4792
4793         trigobj.objectId = CreateTrigger(fk_trigger, true);
4794
4795         /* Register dependency from trigger to constraint */
4796         recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
4797 }
4798
4799 /*
4800  * fkMatchTypeToString -
4801  *        convert FKCONSTR_MATCH_xxx code to string to use in trigger args
4802  */
4803 static char *
4804 fkMatchTypeToString(char match_type)
4805 {
4806         switch (match_type)
4807         {
4808                 case FKCONSTR_MATCH_FULL:
4809                         return pstrdup("FULL");
4810                 case FKCONSTR_MATCH_PARTIAL:
4811                         return pstrdup("PARTIAL");
4812                 case FKCONSTR_MATCH_UNSPECIFIED:
4813                         return pstrdup("UNSPECIFIED");
4814                 default:
4815                         elog(ERROR, "unrecognized match type: %d",
4816                                  (int) match_type);
4817         }
4818         return NULL;                            /* can't get here */
4819 }
4820
4821 /*
4822  * ALTER TABLE DROP CONSTRAINT
4823  */
4824 static void
4825 ATPrepDropConstraint(List **wqueue, Relation rel,
4826                                          bool recurse, AlterTableCmd *cmd)
4827 {
4828         /*
4829          * We don't want errors or noise from child tables, so we have to pass
4830          * down a modified command.
4831          */
4832         if (recurse)
4833         {
4834                 AlterTableCmd *childCmd = copyObject(cmd);
4835
4836                 childCmd->subtype = AT_DropConstraintQuietly;
4837                 ATSimpleRecursion(wqueue, rel, childCmd, recurse);
4838         }
4839 }
4840
4841 static void
4842 ATExecDropConstraint(Relation rel, const char *constrName,
4843                                          DropBehavior behavior, bool quiet)
4844 {
4845         int                     deleted;
4846
4847         deleted = RemoveRelConstraints(rel, constrName, behavior);
4848
4849         if (!quiet)
4850         {
4851                 /* If zero constraints deleted, complain */
4852                 if (deleted == 0)
4853                         ereport(ERROR,
4854                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
4855                                          errmsg("constraint \"%s\" does not exist",
4856                                                         constrName)));
4857                 /* Otherwise if more than one constraint deleted, notify */
4858                 else if (deleted > 1)
4859                         ereport(NOTICE,
4860                                         (errmsg("multiple constraints named \"%s\" were dropped",
4861                                                         constrName)));
4862         }
4863 }
4864
4865 /*
4866  * ALTER COLUMN TYPE
4867  */
4868 static void
4869 ATPrepAlterColumnType(List **wqueue,
4870                                           AlteredTableInfo *tab, Relation rel,
4871                                           bool recurse, bool recursing,
4872                                           AlterTableCmd *cmd)
4873 {
4874         char       *colName = cmd->name;
4875         TypeName   *typename = (TypeName *) cmd->def;
4876         HeapTuple       tuple;
4877         Form_pg_attribute attTup;
4878         AttrNumber      attnum;
4879         Oid                     targettype;
4880         Node       *transform;
4881         NewColumnValue *newval;
4882         ParseState *pstate = make_parsestate(NULL);
4883
4884         /* lookup the attribute so we can check inheritance status */
4885         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4886         if (!HeapTupleIsValid(tuple))
4887                 ereport(ERROR,
4888                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4889                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4890                                                 colName, RelationGetRelationName(rel))));
4891         attTup = (Form_pg_attribute) GETSTRUCT(tuple);
4892         attnum = attTup->attnum;
4893
4894         /* Can't alter a system attribute */
4895         if (attnum <= 0)
4896                 ereport(ERROR,
4897                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4898                                  errmsg("cannot alter system column \"%s\"",
4899                                                 colName)));
4900
4901         /* Don't alter inherited columns */
4902         if (attTup->attinhcount > 0 && !recursing)
4903                 ereport(ERROR,
4904                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4905                                  errmsg("cannot alter inherited column \"%s\"",
4906                                                 colName)));
4907
4908         /* Look up the target type */
4909         targettype = typenameTypeId(NULL, typename);
4910
4911         /* make sure datatype is legal for a column */
4912         CheckAttributeType(colName, targettype);
4913
4914         /*
4915          * Set up an expression to transform the old data value to the new type.
4916          * If a USING option was given, transform and use that expression, else
4917          * just take the old value and try to coerce it.  We do this first so that
4918          * type incompatibility can be detected before we waste effort, and
4919          * because we need the expression to be parsed against the original table
4920          * rowtype.
4921          */
4922         if (cmd->transform)
4923         {
4924                 RangeTblEntry *rte;
4925
4926                 /* Expression must be able to access vars of old table */
4927                 rte = addRangeTableEntryForRelation(pstate,
4928                                                                                         rel,
4929                                                                                         NULL,
4930                                                                                         false,
4931                                                                                         true);
4932                 addRTEtoQuery(pstate, rte, false, true, true);
4933
4934                 transform = transformExpr(pstate, cmd->transform);
4935
4936                 /* It can't return a set */
4937                 if (expression_returns_set(transform))
4938                         ereport(ERROR,
4939                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
4940                                          errmsg("transform expression must not return a set")));
4941
4942                 /* No subplans or aggregates, either... */
4943                 if (pstate->p_hasSubLinks)
4944                         ereport(ERROR,
4945                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4946                                          errmsg("cannot use subquery in transform expression")));
4947                 if (pstate->p_hasAggs)
4948                         ereport(ERROR,
4949                                         (errcode(ERRCODE_GROUPING_ERROR),
4950                         errmsg("cannot use aggregate function in transform expression")));
4951         }
4952         else
4953         {
4954                 transform = (Node *) makeVar(1, attnum,
4955                                                                          attTup->atttypid, attTup->atttypmod,
4956                                                                          0);
4957         }
4958
4959         transform = coerce_to_target_type(pstate,
4960                                                                           transform, exprType(transform),
4961                                                                           targettype, typename->typmod,
4962                                                                           COERCION_ASSIGNMENT,
4963                                                                           COERCE_IMPLICIT_CAST);
4964         if (transform == NULL)
4965                 ereport(ERROR,
4966                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
4967                                  errmsg("column \"%s\" cannot be cast to type \"%s\"",
4968                                                 colName, TypeNameToString(typename))));
4969
4970         /*
4971          * Add a work queue item to make ATRewriteTable update the column
4972          * contents.
4973          */
4974         newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
4975         newval->attnum = attnum;
4976         newval->expr = (Expr *) transform;
4977
4978         tab->newvals = lappend(tab->newvals, newval);
4979
4980         ReleaseSysCache(tuple);
4981
4982         /*
4983          * The recursion case is handled by ATSimpleRecursion.  However, if we are
4984          * told not to recurse, there had better not be any child tables; else the
4985          * alter would put them out of step.
4986          */
4987         if (recurse)
4988                 ATSimpleRecursion(wqueue, rel, cmd, recurse);
4989         else if (!recursing &&
4990                          find_inheritance_children(RelationGetRelid(rel)) != NIL)
4991                 ereport(ERROR,
4992                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4993                                  errmsg("type of inherited column \"%s\" must be changed in child tables too",
4994                                                 colName)));
4995 }
4996
4997 static void
4998 ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
4999                                           const char *colName, TypeName *typename)
5000 {
5001         HeapTuple       heapTup;
5002         Form_pg_attribute attTup;
5003         AttrNumber      attnum;
5004         HeapTuple       typeTuple;
5005         Form_pg_type tform;
5006         Oid                     targettype;
5007         Node       *defaultexpr;
5008         Relation        attrelation;
5009         Relation        depRel;
5010         ScanKeyData key[3];
5011         SysScanDesc scan;
5012         HeapTuple       depTup;
5013
5014         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
5015
5016         /* Look up the target column */
5017         heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
5018         if (!HeapTupleIsValid(heapTup))         /* shouldn't happen */
5019                 ereport(ERROR,
5020                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
5021                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
5022                                                 colName, RelationGetRelationName(rel))));
5023         attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
5024         attnum = attTup->attnum;
5025
5026         /* Check for multiple ALTER TYPE on same column --- can't cope */
5027         if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
5028                 attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
5029                 ereport(ERROR,
5030                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5031                                  errmsg("cannot alter type of column \"%s\" twice",
5032                                                 colName)));
5033
5034         /* Look up the target type (should not fail, since prep found it) */
5035         typeTuple = typenameType(NULL, typename);
5036         tform = (Form_pg_type) GETSTRUCT(typeTuple);
5037         targettype = HeapTupleGetOid(typeTuple);
5038
5039         /*
5040          * If there is a default expression for the column, get it and ensure we
5041          * can coerce it to the new datatype.  (We must do this before changing
5042          * the column type, because build_column_default itself will try to
5043          * coerce, and will not issue the error message we want if it fails.)
5044          *
5045          * We remove any implicit coercion steps at the top level of the old
5046          * default expression; this has been agreed to satisfy the principle of
5047          * least surprise.      (The conversion to the new column type should act like
5048          * it started from what the user sees as the stored expression, and the
5049          * implicit coercions aren't going to be shown.)
5050          */
5051         if (attTup->atthasdef)
5052         {
5053                 defaultexpr = build_column_default(rel, attnum);
5054                 Assert(defaultexpr);
5055                 defaultexpr = strip_implicit_coercions(defaultexpr);
5056                 defaultexpr = coerce_to_target_type(NULL,               /* no UNKNOWN params */
5057                                                                                   defaultexpr, exprType(defaultexpr),
5058                                                                                         targettype, typename->typmod,
5059                                                                                         COERCION_ASSIGNMENT,
5060                                                                                         COERCE_IMPLICIT_CAST);
5061                 if (defaultexpr == NULL)
5062                         ereport(ERROR,
5063                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
5064                         errmsg("default for column \"%s\" cannot be cast to type \"%s\"",
5065                                    colName, TypeNameToString(typename))));
5066         }
5067         else
5068                 defaultexpr = NULL;
5069
5070         /*
5071          * Find everything that depends on the column (constraints, indexes, etc),
5072          * and record enough information to let us recreate the objects.
5073          *
5074          * The actual recreation does not happen here, but only after we have
5075          * performed all the individual ALTER TYPE operations.  We have to save
5076          * the info before executing ALTER TYPE, though, else the deparser will
5077          * get confused.
5078          *
5079          * There could be multiple entries for the same object, so we must check
5080          * to ensure we process each one only once.  Note: we assume that an index
5081          * that implements a constraint will not show a direct dependency on the
5082          * column.
5083          */
5084         depRel = heap_open(DependRelationId, RowExclusiveLock);
5085
5086         ScanKeyInit(&key[0],
5087                                 Anum_pg_depend_refclassid,
5088                                 BTEqualStrategyNumber, F_OIDEQ,
5089                                 ObjectIdGetDatum(RelationRelationId));
5090         ScanKeyInit(&key[1],
5091                                 Anum_pg_depend_refobjid,
5092                                 BTEqualStrategyNumber, F_OIDEQ,
5093                                 ObjectIdGetDatum(RelationGetRelid(rel)));
5094         ScanKeyInit(&key[2],
5095                                 Anum_pg_depend_refobjsubid,
5096                                 BTEqualStrategyNumber, F_INT4EQ,
5097                                 Int32GetDatum((int32) attnum));
5098
5099         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
5100                                                           SnapshotNow, 3, key);
5101
5102         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
5103         {
5104                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
5105                 ObjectAddress foundObject;
5106
5107                 /* We don't expect any PIN dependencies on columns */
5108                 if (foundDep->deptype == DEPENDENCY_PIN)
5109                         elog(ERROR, "cannot alter type of a pinned column");
5110
5111                 foundObject.classId = foundDep->classid;
5112                 foundObject.objectId = foundDep->objid;
5113                 foundObject.objectSubId = foundDep->objsubid;
5114
5115                 switch (getObjectClass(&foundObject))
5116                 {
5117                         case OCLASS_CLASS:
5118                                 {
5119                                         char            relKind = get_rel_relkind(foundObject.objectId);
5120
5121                                         if (relKind == RELKIND_INDEX)
5122                                         {
5123                                                 Assert(foundObject.objectSubId == 0);
5124                                                 if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
5125                                                 {
5126                                                         tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
5127                                                                                                            foundObject.objectId);
5128                                                         tab->changedIndexDefs = lappend(tab->changedIndexDefs,
5129                                                            pg_get_indexdef_string(foundObject.objectId));
5130                                                 }
5131                                         }
5132                                         else if (relKind == RELKIND_SEQUENCE)
5133                                         {
5134                                                 /*
5135                                                  * This must be a SERIAL column's sequence.  We need
5136                                                  * not do anything to it.
5137                                                  */
5138                                                 Assert(foundObject.objectSubId == 0);
5139                                         }
5140                                         else
5141                                         {
5142                                                 /* Not expecting any other direct dependencies... */
5143                                                 elog(ERROR, "unexpected object depending on column: %s",
5144                                                          getObjectDescription(&foundObject));
5145                                         }
5146                                         break;
5147                                 }
5148
5149                         case OCLASS_CONSTRAINT:
5150                                 Assert(foundObject.objectSubId == 0);
5151                                 if (!list_member_oid(tab->changedConstraintOids,
5152                                                                          foundObject.objectId))
5153                                 {
5154                                         char       *defstring = pg_get_constraintdef_string(foundObject.objectId);
5155
5156                                         /*
5157                                          * Put NORMAL dependencies at the front of the list and
5158                                          * AUTO dependencies at the back.  This makes sure that
5159                                          * foreign-key constraints depending on this column will
5160                                          * be dropped before unique or primary-key constraints of
5161                                          * the column; which we must have because the FK
5162                                          * constraints depend on the indexes belonging to the
5163                                          * unique constraints.
5164                                          */
5165                                         if (foundDep->deptype == DEPENDENCY_NORMAL)
5166                                         {
5167                                                 tab->changedConstraintOids =
5168                                                         lcons_oid(foundObject.objectId,
5169                                                                           tab->changedConstraintOids);
5170                                                 tab->changedConstraintDefs =
5171                                                         lcons(defstring,
5172                                                                   tab->changedConstraintDefs);
5173                                         }
5174                                         else
5175                                         {
5176                                                 tab->changedConstraintOids =
5177                                                         lappend_oid(tab->changedConstraintOids,
5178                                                                                 foundObject.objectId);
5179                                                 tab->changedConstraintDefs =
5180                                                         lappend(tab->changedConstraintDefs,
5181                                                                         defstring);
5182                                         }
5183                                 }
5184                                 break;
5185
5186                         case OCLASS_REWRITE:
5187                                 /* XXX someday see if we can cope with revising views */
5188                                 ereport(ERROR,
5189                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5190                                                  errmsg("cannot alter type of a column used by a view or rule"),
5191                                                  errdetail("%s depends on column \"%s\"",
5192                                                                    getObjectDescription(&foundObject),
5193                                                                    colName)));
5194                                 break;
5195
5196                         case OCLASS_DEFAULT:
5197
5198                                 /*
5199                                  * Ignore the column's default expression, since we will fix
5200                                  * it below.
5201                                  */
5202                                 Assert(defaultexpr);
5203                                 break;
5204
5205                         case OCLASS_PROC:
5206                         case OCLASS_TYPE:
5207                         case OCLASS_CAST:
5208                         case OCLASS_CONVERSION:
5209                         case OCLASS_LANGUAGE:
5210                         case OCLASS_OPERATOR:
5211                         case OCLASS_OPCLASS:
5212                         case OCLASS_TRIGGER:
5213                         case OCLASS_SCHEMA:
5214
5215                                 /*
5216                                  * We don't expect any of these sorts of objects to depend on
5217                                  * a column.
5218                                  */
5219                                 elog(ERROR, "unexpected object depending on column: %s",
5220                                          getObjectDescription(&foundObject));
5221                                 break;
5222
5223                         default:
5224                                 elog(ERROR, "unrecognized object class: %u",
5225                                          foundObject.classId);
5226                 }
5227         }
5228
5229         systable_endscan(scan);
5230
5231         /*
5232          * Now scan for dependencies of this column on other things.  The only
5233          * thing we should find is the dependency on the column datatype, which we
5234          * want to remove.
5235          */
5236         ScanKeyInit(&key[0],
5237                                 Anum_pg_depend_classid,
5238                                 BTEqualStrategyNumber, F_OIDEQ,
5239                                 ObjectIdGetDatum(RelationRelationId));
5240         ScanKeyInit(&key[1],
5241                                 Anum_pg_depend_objid,
5242                                 BTEqualStrategyNumber, F_OIDEQ,
5243                                 ObjectIdGetDatum(RelationGetRelid(rel)));
5244         ScanKeyInit(&key[2],
5245                                 Anum_pg_depend_objsubid,
5246                                 BTEqualStrategyNumber, F_INT4EQ,
5247                                 Int32GetDatum((int32) attnum));
5248
5249         scan = systable_beginscan(depRel, DependDependerIndexId, true,
5250                                                           SnapshotNow, 3, key);
5251
5252         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
5253         {
5254                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
5255
5256                 if (foundDep->deptype != DEPENDENCY_NORMAL)
5257                         elog(ERROR, "found unexpected dependency type '%c'",
5258                                  foundDep->deptype);
5259                 if (foundDep->refclassid != TypeRelationId ||
5260                         foundDep->refobjid != attTup->atttypid)
5261                         elog(ERROR, "found unexpected dependency for column");
5262
5263                 simple_heap_delete(depRel, &depTup->t_self);
5264         }
5265
5266         systable_endscan(scan);
5267
5268         heap_close(depRel, RowExclusiveLock);
5269
5270         /*
5271          * Here we go --- change the recorded column type.      (Note heapTup is a
5272          * copy of the syscache entry, so okay to scribble on.)
5273          */
5274         attTup->atttypid = targettype;
5275         attTup->atttypmod = typename->typmod;
5276         attTup->attndims = list_length(typename->arrayBounds);
5277         attTup->attlen = tform->typlen;
5278         attTup->attbyval = tform->typbyval;
5279         attTup->attalign = tform->typalign;
5280         attTup->attstorage = tform->typstorage;
5281
5282         ReleaseSysCache(typeTuple);
5283
5284         simple_heap_update(attrelation, &heapTup->t_self, heapTup);
5285
5286         /* keep system catalog indexes current */
5287         CatalogUpdateIndexes(attrelation, heapTup);
5288
5289         heap_close(attrelation, RowExclusiveLock);
5290
5291         /* Install dependency on new datatype */
5292         add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
5293
5294         /*
5295          * Drop any pg_statistic entry for the column, since it's now wrong type
5296          */
5297         RemoveStatistics(RelationGetRelid(rel), attnum);
5298
5299         /*
5300          * Update the default, if present, by brute force --- remove and re-add
5301          * the default.  Probably unsafe to take shortcuts, since the new version
5302          * may well have additional dependencies.  (It's okay to do this now,
5303          * rather than after other ALTER TYPE commands, since the default won't
5304          * depend on other column types.)
5305          */
5306         if (defaultexpr)
5307         {
5308                 /* Must make new row visible since it will be updated again */
5309                 CommandCounterIncrement();
5310
5311                 /*
5312                  * We use RESTRICT here for safety, but at present we do not expect
5313                  * anything to depend on the default.
5314                  */
5315                 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
5316
5317                 StoreAttrDefault(rel, attnum, nodeToString(defaultexpr));
5318         }
5319
5320         /* Cleanup */
5321         heap_freetuple(heapTup);
5322 }
5323
5324 /*
5325  * Cleanup after we've finished all the ALTER TYPE operations for a
5326  * particular relation.  We have to drop and recreate all the indexes
5327  * and constraints that depend on the altered columns.
5328  */
5329 static void
5330 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
5331 {
5332         ObjectAddress obj;
5333         ListCell   *l;
5334
5335         /*
5336          * Re-parse the index and constraint definitions, and attach them to the
5337          * appropriate work queue entries.      We do this before dropping because in
5338          * the case of a FOREIGN KEY constraint, we might not yet have exclusive
5339          * lock on the table the constraint is attached to, and we need to get
5340          * that before dropping.  It's safe because the parser won't actually look
5341          * at the catalogs to detect the existing entry.
5342          */
5343         foreach(l, tab->changedIndexDefs)
5344                 ATPostAlterTypeParse((char *) lfirst(l), wqueue);
5345         foreach(l, tab->changedConstraintDefs)
5346                 ATPostAlterTypeParse((char *) lfirst(l), wqueue);
5347
5348         /*
5349          * Now we can drop the existing constraints and indexes --- constraints
5350          * first, since some of them might depend on the indexes.  In fact, we
5351          * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
5352          * we already ordered the constraint list to ensure that would happen. It
5353          * should be okay to use DROP_RESTRICT here, since nothing else should be
5354          * depending on these objects.
5355          */
5356         foreach(l, tab->changedConstraintOids)
5357         {
5358                 obj.classId = ConstraintRelationId;
5359                 obj.objectId = lfirst_oid(l);
5360                 obj.objectSubId = 0;
5361                 performDeletion(&obj, DROP_RESTRICT);
5362         }
5363
5364         foreach(l, tab->changedIndexOids)
5365         {
5366                 obj.classId = RelationRelationId;
5367                 obj.objectId = lfirst_oid(l);
5368                 obj.objectSubId = 0;
5369                 performDeletion(&obj, DROP_RESTRICT);
5370         }
5371
5372         /*
5373          * The objects will get recreated during subsequent passes over the work
5374          * queue.
5375          */
5376 }
5377
5378 static void
5379 ATPostAlterTypeParse(char *cmd, List **wqueue)
5380 {
5381         List       *raw_parsetree_list;
5382         List       *querytree_list;
5383         ListCell   *list_item;
5384
5385         /*
5386          * We expect that we only have to do raw parsing and parse analysis, not
5387          * any rule rewriting, since these will all be utility statements.
5388          */
5389         raw_parsetree_list = raw_parser(cmd);
5390         querytree_list = NIL;
5391         foreach(list_item, raw_parsetree_list)
5392         {
5393                 Node       *parsetree = (Node *) lfirst(list_item);
5394
5395                 querytree_list = list_concat(querytree_list,
5396                                                                          parse_analyze(parsetree, cmd, NULL, 0));
5397         }
5398
5399         /*
5400          * Attach each generated command to the proper place in the work queue.
5401          * Note this could result in creation of entirely new work-queue entries.
5402          */
5403         foreach(list_item, querytree_list)
5404         {
5405                 Query      *query = (Query *) lfirst(list_item);
5406                 Relation        rel;
5407                 AlteredTableInfo *tab;
5408
5409                 Assert(IsA(query, Query));
5410                 Assert(query->commandType == CMD_UTILITY);
5411                 switch (nodeTag(query->utilityStmt))
5412                 {
5413                         case T_IndexStmt:
5414                                 {
5415                                         IndexStmt  *stmt = (IndexStmt *) query->utilityStmt;
5416                                         AlterTableCmd *newcmd;
5417
5418                                         rel = relation_openrv(stmt->relation, AccessExclusiveLock);
5419                                         tab = ATGetQueueEntry(wqueue, rel);
5420                                         newcmd = makeNode(AlterTableCmd);
5421                                         newcmd->subtype = AT_ReAddIndex;
5422                                         newcmd->def = (Node *) stmt;
5423                                         tab->subcmds[AT_PASS_OLD_INDEX] =
5424                                                 lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
5425                                         relation_close(rel, NoLock);
5426                                         break;
5427                                 }
5428                         case T_AlterTableStmt:
5429                                 {
5430                                         AlterTableStmt *stmt = (AlterTableStmt *) query->utilityStmt;
5431                                         ListCell   *lcmd;
5432
5433                                         rel = relation_openrv(stmt->relation, AccessExclusiveLock);
5434                                         tab = ATGetQueueEntry(wqueue, rel);
5435                                         foreach(lcmd, stmt->cmds)
5436                                         {
5437                                                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
5438
5439                                                 switch (cmd->subtype)
5440                                                 {
5441                                                         case AT_AddIndex:
5442                                                                 cmd->subtype = AT_ReAddIndex;
5443                                                                 tab->subcmds[AT_PASS_OLD_INDEX] =
5444                                                                         lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
5445                                                                 break;
5446                                                         case AT_AddConstraint:
5447                                                                 tab->subcmds[AT_PASS_OLD_CONSTR] =
5448                                                                         lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
5449                                                                 break;
5450                                                         default:
5451                                                                 elog(ERROR, "unexpected statement type: %d",
5452                                                                          (int) cmd->subtype);
5453                                                 }
5454                                         }
5455                                         relation_close(rel, NoLock);
5456                                         break;
5457                                 }
5458                         default:
5459                                 elog(ERROR, "unexpected statement type: %d",
5460                                          (int) nodeTag(query->utilityStmt));
5461                 }
5462         }
5463 }
5464
5465
5466 /*
5467  * ALTER TABLE OWNER
5468  *
5469  * recursing is true if we are recursing from a table to its indexes,
5470  * sequences, or toast table.  We don't allow the ownership of those things to
5471  * be changed separately from the parent table.  Also, we can skip permission
5472  * checks (this is necessary not just an optimization, else we'd fail to
5473  * handle toast tables properly).
5474  */
5475 void
5476 ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
5477 {
5478         Relation        target_rel;
5479         Relation        class_rel;
5480         HeapTuple       tuple;
5481         Form_pg_class tuple_class;
5482
5483         /*
5484          * Get exclusive lock till end of transaction on the target table. Use
5485          * relation_open so that we can work on indexes and sequences.
5486          */
5487         target_rel = relation_open(relationOid, AccessExclusiveLock);
5488
5489         /* Get its pg_class tuple, too */
5490         class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5491
5492         tuple = SearchSysCache(RELOID,
5493                                                    ObjectIdGetDatum(relationOid),
5494                                                    0, 0, 0);
5495         if (!HeapTupleIsValid(tuple))
5496                 elog(ERROR, "cache lookup failed for relation %u", relationOid);
5497         tuple_class = (Form_pg_class) GETSTRUCT(tuple);
5498
5499         /* Can we change the ownership of this tuple? */
5500         switch (tuple_class->relkind)
5501         {
5502                 case RELKIND_RELATION:
5503                 case RELKIND_VIEW:
5504                         /* ok to change owner */
5505                         break;
5506                 case RELKIND_INDEX:
5507                         if (!recursing)
5508                         {
5509                                 /*
5510                                  * Because ALTER INDEX OWNER used to be allowed, and in fact
5511                                  * is generated by old versions of pg_dump, we give a warning
5512                                  * and do nothing rather than erroring out.  Also, to avoid
5513                                  * unnecessary chatter while restoring those old dumps, say
5514                                  * nothing at all if the command would be a no-op anyway.
5515                                  */
5516                                 if (tuple_class->relowner != newOwnerId)
5517                                         ereport(WARNING,
5518                                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5519                                                          errmsg("cannot change owner of index \"%s\"",
5520                                                                         NameStr(tuple_class->relname)),
5521                                                          errhint("Change the ownership of the index's table, instead.")));
5522                                 /* quick hack to exit via the no-op path */
5523                                 newOwnerId = tuple_class->relowner;
5524                         }
5525                         break;
5526                 case RELKIND_SEQUENCE:
5527                         if (!recursing &&
5528                                 tuple_class->relowner != newOwnerId)
5529                         {
5530                                 /* if it's an owned sequence, disallow changing it by itself */
5531                                 Oid                     tableId;
5532                                 int32           colId;
5533
5534                                 if (sequenceIsOwned(relationOid, &tableId, &colId))
5535                                         ereport(ERROR,
5536                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5537                                                          errmsg("cannot change owner of sequence \"%s\"",
5538                                                                         NameStr(tuple_class->relname)),
5539                                           errdetail("Sequence \"%s\" is linked to table \"%s\".",
5540                                                                 NameStr(tuple_class->relname),
5541                                                                 get_rel_name(tableId))));
5542                         }
5543                         break;
5544                 case RELKIND_TOASTVALUE:
5545                         if (recursing)
5546                                 break;
5547                         /* FALL THRU */
5548                 default:
5549                         ereport(ERROR,
5550                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5551                                          errmsg("\"%s\" is not a table, view, or sequence",
5552                                                         NameStr(tuple_class->relname))));
5553         }
5554
5555         /*
5556          * If the new owner is the same as the existing owner, consider the
5557          * command to have succeeded.  This is for dump restoration purposes.
5558          */
5559         if (tuple_class->relowner != newOwnerId)
5560         {
5561                 Datum           repl_val[Natts_pg_class];
5562                 char            repl_null[Natts_pg_class];
5563                 char            repl_repl[Natts_pg_class];
5564                 Acl                *newAcl;
5565                 Datum           aclDatum;
5566                 bool            isNull;
5567                 HeapTuple       newtuple;
5568
5569                 /* skip permission checks when recursing to index or toast table */
5570                 if (!recursing)
5571                 {
5572                         /* Superusers can always do it */
5573                         if (!superuser())
5574                         {
5575                                 Oid                     namespaceOid = tuple_class->relnamespace;
5576                                 AclResult       aclresult;
5577
5578                                 /* Otherwise, must be owner of the existing object */
5579                                 if (!pg_class_ownercheck(relationOid, GetUserId()))
5580                                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
5581                                                                    RelationGetRelationName(target_rel));
5582
5583                                 /* Must be able to become new owner */
5584                                 check_is_member_of_role(GetUserId(), newOwnerId);
5585
5586                                 /* New owner must have CREATE privilege on namespace */
5587                                 aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
5588                                                                                                   ACL_CREATE);
5589                                 if (aclresult != ACLCHECK_OK)
5590                                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
5591                                                                    get_namespace_name(namespaceOid));
5592                         }
5593                 }
5594
5595                 memset(repl_null, ' ', sizeof(repl_null));
5596                 memset(repl_repl, ' ', sizeof(repl_repl));
5597
5598                 repl_repl[Anum_pg_class_relowner - 1] = 'r';
5599                 repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
5600
5601                 /*
5602                  * Determine the modified ACL for the new owner.  This is only
5603                  * necessary when the ACL is non-null.
5604                  */
5605                 aclDatum = SysCacheGetAttr(RELOID, tuple,
5606                                                                    Anum_pg_class_relacl,
5607                                                                    &isNull);
5608                 if (!isNull)
5609                 {
5610                         newAcl = aclnewowner(DatumGetAclP(aclDatum),
5611                                                                  tuple_class->relowner, newOwnerId);
5612                         repl_repl[Anum_pg_class_relacl - 1] = 'r';
5613                         repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
5614                 }
5615
5616                 newtuple = heap_modifytuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl);
5617
5618                 simple_heap_update(class_rel, &newtuple->t_self, newtuple);
5619                 CatalogUpdateIndexes(class_rel, newtuple);
5620
5621                 heap_freetuple(newtuple);
5622
5623                 /* Update owner dependency reference */
5624                 changeDependencyOnOwner(RelationRelationId, relationOid, newOwnerId);
5625
5626                 /*
5627                  * Also change the ownership of the table's rowtype, if it has one
5628                  */
5629                 if (tuple_class->relkind != RELKIND_INDEX)
5630                         AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId);
5631
5632                 /*
5633                  * If we are operating on a table, also change the ownership of any
5634                  * indexes and sequences that belong to the table, as well as the
5635                  * table's toast table (if it has one)
5636                  */
5637                 if (tuple_class->relkind == RELKIND_RELATION ||
5638                         tuple_class->relkind == RELKIND_TOASTVALUE)
5639                 {
5640                         List       *index_oid_list;
5641                         ListCell   *i;
5642
5643                         /* Find all the indexes belonging to this relation */
5644                         index_oid_list = RelationGetIndexList(target_rel);
5645
5646                         /* For each index, recursively change its ownership */
5647                         foreach(i, index_oid_list)
5648                                 ATExecChangeOwner(lfirst_oid(i), newOwnerId, true);
5649
5650                         list_free(index_oid_list);
5651                 }
5652
5653                 if (tuple_class->relkind == RELKIND_RELATION)
5654                 {
5655                         /* If it has a toast table, recurse to change its ownership */
5656                         if (tuple_class->reltoastrelid != InvalidOid)
5657                                 ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId,
5658                                                                   true);
5659
5660                         /* If it has dependent sequences, recurse to change them too */
5661                         change_owner_recurse_to_sequences(relationOid, newOwnerId);
5662                 }
5663         }
5664
5665         ReleaseSysCache(tuple);
5666         heap_close(class_rel, RowExclusiveLock);
5667         relation_close(target_rel, NoLock);
5668 }
5669
5670 /*
5671  * change_owner_recurse_to_sequences
5672  *
5673  * Helper function for ATExecChangeOwner.  Examines pg_depend searching
5674  * for sequences that are dependent on serial columns, and changes their
5675  * ownership.
5676  */
5677 static void
5678 change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId)
5679 {
5680         Relation        depRel;
5681         SysScanDesc scan;
5682         ScanKeyData key[2];
5683         HeapTuple       tup;
5684
5685         /*
5686          * SERIAL sequences are those having an auto dependency on one of the
5687          * table's columns (we don't care *which* column, exactly).
5688          */
5689         depRel = heap_open(DependRelationId, AccessShareLock);
5690
5691         ScanKeyInit(&key[0],
5692                                 Anum_pg_depend_refclassid,
5693                                 BTEqualStrategyNumber, F_OIDEQ,
5694                                 ObjectIdGetDatum(RelationRelationId));
5695         ScanKeyInit(&key[1],
5696                                 Anum_pg_depend_refobjid,
5697                                 BTEqualStrategyNumber, F_OIDEQ,
5698                                 ObjectIdGetDatum(relationOid));
5699         /* we leave refobjsubid unspecified */
5700
5701         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
5702                                                           SnapshotNow, 2, key);
5703
5704         while (HeapTupleIsValid(tup = systable_getnext(scan)))
5705         {
5706                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
5707                 Relation        seqRel;
5708
5709                 /* skip dependencies other than auto dependencies on columns */
5710                 if (depForm->refobjsubid == 0 ||
5711                         depForm->classid != RelationRelationId ||
5712                         depForm->objsubid != 0 ||
5713                         depForm->deptype != DEPENDENCY_AUTO)
5714                         continue;
5715
5716                 /* Use relation_open just in case it's an index */
5717                 seqRel = relation_open(depForm->objid, AccessExclusiveLock);
5718
5719                 /* skip non-sequence relations */
5720                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
5721                 {
5722                         /* No need to keep the lock */
5723                         relation_close(seqRel, AccessExclusiveLock);
5724                         continue;
5725                 }
5726
5727                 /* We don't need to close the sequence while we alter it. */
5728                 ATExecChangeOwner(depForm->objid, newOwnerId, true);
5729
5730                 /* Now we can close it.  Keep the lock till end of transaction. */
5731                 relation_close(seqRel, NoLock);
5732         }
5733
5734         systable_endscan(scan);
5735
5736         relation_close(depRel, AccessShareLock);
5737 }
5738
5739 /*
5740  * ALTER TABLE CLUSTER ON
5741  *
5742  * The only thing we have to do is to change the indisclustered bits.
5743  */
5744 static void
5745 ATExecClusterOn(Relation rel, const char *indexName)
5746 {
5747         Oid                     indexOid;
5748
5749         indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
5750
5751         if (!OidIsValid(indexOid))
5752                 ereport(ERROR,
5753                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5754                                  errmsg("index \"%s\" for table \"%s\" does not exist",
5755                                                 indexName, RelationGetRelationName(rel))));
5756
5757         /* Check index is valid to cluster on */
5758         check_index_is_clusterable(rel, indexOid, false);
5759
5760         /* And do the work */
5761         mark_index_clustered(rel, indexOid);
5762 }
5763
5764 /*
5765  * ALTER TABLE SET WITHOUT CLUSTER
5766  *
5767  * We have to find any indexes on the table that have indisclustered bit
5768  * set and turn it off.
5769  */
5770 static void
5771 ATExecDropCluster(Relation rel)
5772 {
5773         mark_index_clustered(rel, InvalidOid);
5774 }
5775
5776 /*
5777  * ALTER TABLE SET TABLESPACE
5778  */
5779 static void
5780 ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
5781 {
5782         Oid                     tablespaceId;
5783         AclResult       aclresult;
5784
5785         /* Check that the tablespace exists */
5786         tablespaceId = get_tablespace_oid(tablespacename);
5787         if (!OidIsValid(tablespaceId))
5788                 ereport(ERROR,
5789                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5790                                  errmsg("tablespace \"%s\" does not exist", tablespacename)));
5791
5792         /* Check its permissions */
5793         aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
5794         if (aclresult != ACLCHECK_OK)
5795                 aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
5796
5797         /* Save info for Phase 3 to do the real work */
5798         if (OidIsValid(tab->newTableSpace))
5799                 ereport(ERROR,
5800                                 (errcode(ERRCODE_SYNTAX_ERROR),
5801                                  errmsg("cannot have multiple SET TABLESPACE subcommands")));
5802         tab->newTableSpace = tablespaceId;
5803 }
5804
5805 /*
5806  * ALTER TABLE/INDEX SET (...) or RESET (...)
5807  */
5808 static void
5809 ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
5810 {
5811         Oid                     relid;
5812         Relation        pgclass;
5813         HeapTuple       tuple;
5814         HeapTuple       newtuple;
5815         Datum           datum;
5816         bool            isnull;
5817         Datum           newOptions;
5818         Datum           repl_val[Natts_pg_class];
5819         char            repl_null[Natts_pg_class];
5820         char            repl_repl[Natts_pg_class];
5821
5822         if (defList == NIL)
5823                 return;                                 /* nothing to do */
5824
5825         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
5826
5827         /* Get the old reloptions */
5828         relid = RelationGetRelid(rel);
5829         tuple = SearchSysCache(RELOID,
5830                                                    ObjectIdGetDatum(relid),
5831                                                    0, 0, 0);
5832         if (!HeapTupleIsValid(tuple))
5833                 elog(ERROR, "cache lookup failed for relation %u", relid);
5834
5835         datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
5836
5837         /* Generate new proposed reloptions (text array) */
5838         newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
5839                                                                          defList, false, isReset);
5840
5841         /* Validate */
5842         switch (rel->rd_rel->relkind)
5843         {
5844                 case RELKIND_RELATION:
5845                 case RELKIND_TOASTVALUE:
5846                         (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
5847                         break;
5848                 case RELKIND_INDEX:
5849                         (void) index_reloptions(rel->rd_am->amoptions, newOptions, true);
5850                         break;
5851                 default:
5852                         ereport(ERROR,
5853                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5854                                          errmsg("\"%s\" is not a table, index, or TOAST table",
5855                                                         RelationGetRelationName(rel))));
5856                         break;
5857         }
5858
5859         /*
5860          * All we need do here is update the pg_class row; the new options will be
5861          * propagated into relcaches during post-commit cache inval.
5862          */
5863         memset(repl_val, 0, sizeof(repl_val));
5864         memset(repl_null, ' ', sizeof(repl_null));
5865         memset(repl_repl, ' ', sizeof(repl_repl));
5866
5867         if (newOptions != (Datum) 0)
5868                 repl_val[Anum_pg_class_reloptions - 1] = newOptions;
5869         else
5870                 repl_null[Anum_pg_class_reloptions - 1] = 'n';
5871
5872         repl_repl[Anum_pg_class_reloptions - 1] = 'r';
5873
5874         newtuple = heap_modifytuple(tuple, RelationGetDescr(pgclass),
5875                                                                 repl_val, repl_null, repl_repl);
5876
5877         simple_heap_update(pgclass, &newtuple->t_self, newtuple);
5878
5879         CatalogUpdateIndexes(pgclass, newtuple);
5880
5881         heap_freetuple(newtuple);
5882
5883         ReleaseSysCache(tuple);
5884
5885         heap_close(pgclass, RowExclusiveLock);
5886 }
5887
5888 /*
5889  * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
5890  * rewriting to be done, so we just want to copy the data as fast as possible.
5891  */
5892 static void
5893 ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
5894 {
5895         Relation        rel;
5896         Oid                     oldTableSpace;
5897         Oid                     reltoastrelid;
5898         Oid                     reltoastidxid;
5899         RelFileNode newrnode;
5900         SMgrRelation dstrel;
5901         Relation        pg_class;
5902         HeapTuple       tuple;
5903         Form_pg_class rd_rel;
5904
5905         /*
5906          * Need lock here in case we are recursing to toast table or index
5907          */
5908         rel = relation_open(tableOid, AccessExclusiveLock);
5909
5910         /*
5911          * We can never allow moving of shared or nailed-in-cache relations,
5912          * because we can't support changing their reltablespace values.
5913          */
5914         if (rel->rd_rel->relisshared || rel->rd_isnailed)
5915                 ereport(ERROR,
5916                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5917                                  errmsg("cannot move system relation \"%s\"",
5918                                                 RelationGetRelationName(rel))));
5919
5920         /*
5921          * Don't allow moving temp tables of other backends ... their local buffer
5922          * manager is not going to cope.
5923          */
5924         if (isOtherTempNamespace(RelationGetNamespace(rel)))
5925                 ereport(ERROR,
5926                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5927                                  errmsg("cannot move temporary tables of other sessions")));
5928
5929         /*
5930          * No work if no change in tablespace.
5931          */
5932         oldTableSpace = rel->rd_rel->reltablespace;
5933         if (newTableSpace == oldTableSpace ||
5934                 (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
5935         {
5936                 relation_close(rel, NoLock);
5937                 return;
5938         }
5939
5940         reltoastrelid = rel->rd_rel->reltoastrelid;
5941         reltoastidxid = rel->rd_rel->reltoastidxid;
5942
5943         /* Get a modifiable copy of the relation's pg_class row */
5944         pg_class = heap_open(RelationRelationId, RowExclusiveLock);
5945
5946         tuple = SearchSysCacheCopy(RELOID,
5947                                                            ObjectIdGetDatum(tableOid),
5948                                                            0, 0, 0);
5949         if (!HeapTupleIsValid(tuple))
5950                 elog(ERROR, "cache lookup failed for relation %u", tableOid);
5951         rd_rel = (Form_pg_class) GETSTRUCT(tuple);
5952
5953         /* create another storage file. Is it a little ugly ? */
5954         /* NOTE: any conflict in relfilenode value will be caught here */
5955         newrnode = rel->rd_node;
5956         newrnode.spcNode = newTableSpace;
5957
5958         dstrel = smgropen(newrnode);
5959         smgrcreate(dstrel, rel->rd_istemp, false);
5960
5961         /* copy relation data to the new physical file */
5962         copy_relation_data(rel, dstrel);
5963
5964         /* schedule unlinking old physical file */
5965         RelationOpenSmgr(rel);
5966         smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
5967
5968         /*
5969          * Now drop smgr references.  The source was already dropped by
5970          * smgrscheduleunlink.
5971          */
5972         smgrclose(dstrel);
5973
5974         /* update the pg_class row */
5975         rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
5976         simple_heap_update(pg_class, &tuple->t_self, tuple);
5977         CatalogUpdateIndexes(pg_class, tuple);
5978
5979         heap_freetuple(tuple);
5980
5981         heap_close(pg_class, RowExclusiveLock);
5982
5983         relation_close(rel, NoLock);
5984
5985         /* Make sure the reltablespace change is visible */
5986         CommandCounterIncrement();
5987
5988         /* Move associated toast relation and/or index, too */
5989         if (OidIsValid(reltoastrelid))
5990                 ATExecSetTableSpace(reltoastrelid, newTableSpace);
5991         if (OidIsValid(reltoastidxid))
5992                 ATExecSetTableSpace(reltoastidxid, newTableSpace);
5993 }
5994
5995 /*
5996  * Copy data, block by block
5997  */
5998 static void
5999 copy_relation_data(Relation rel, SMgrRelation dst)
6000 {
6001         SMgrRelation src;
6002         bool            use_wal;
6003         BlockNumber nblocks;
6004         BlockNumber blkno;
6005         char            buf[BLCKSZ];
6006         Page            page = (Page) buf;
6007
6008         /*
6009          * Since we copy the file directly without looking at the shared buffers,
6010          * we'd better first flush out any pages of the source relation that are
6011          * in shared buffers.  We assume no new changes will be made while we are
6012          * holding exclusive lock on the rel.
6013          */
6014         FlushRelationBuffers(rel);
6015
6016         /*
6017          * We need to log the copied data in WAL iff WAL archiving is enabled AND
6018          * it's not a temp rel.
6019          */
6020         use_wal = XLogArchivingActive() && !rel->rd_istemp;
6021
6022         nblocks = RelationGetNumberOfBlocks(rel);
6023         /* RelationGetNumberOfBlocks will certainly have opened rd_smgr */
6024         src = rel->rd_smgr;
6025
6026         for (blkno = 0; blkno < nblocks; blkno++)
6027         {
6028                 smgrread(src, blkno, buf);
6029
6030                 /* XLOG stuff */
6031                 if (use_wal)
6032                 {
6033                         xl_heap_newpage xlrec;
6034                         XLogRecPtr      recptr;
6035                         XLogRecData rdata[2];
6036
6037                         /* NO ELOG(ERROR) from here till newpage op is logged */
6038                         START_CRIT_SECTION();
6039
6040                         xlrec.node = dst->smgr_rnode;
6041                         xlrec.blkno = blkno;
6042
6043                         rdata[0].data = (char *) &xlrec;
6044                         rdata[0].len = SizeOfHeapNewpage;
6045                         rdata[0].buffer = InvalidBuffer;
6046                         rdata[0].next = &(rdata[1]);
6047
6048                         rdata[1].data = (char *) page;
6049                         rdata[1].len = BLCKSZ;
6050                         rdata[1].buffer = InvalidBuffer;
6051                         rdata[1].next = NULL;
6052
6053                         recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
6054
6055                         PageSetLSN(page, recptr);
6056                         PageSetTLI(page, ThisTimeLineID);
6057
6058                         END_CRIT_SECTION();
6059                 }
6060
6061                 /*
6062                  * Now write the page.  We say isTemp = true even if it's not a temp
6063                  * rel, because there's no need for smgr to schedule an fsync for this
6064                  * write; we'll do it ourselves below.
6065                  */
6066                 smgrwrite(dst, blkno, buf, true);
6067         }
6068
6069         /*
6070          * If the rel isn't temp, we must fsync it down to disk before it's safe
6071          * to commit the transaction.  (For a temp rel we don't care since the rel
6072          * will be uninteresting after a crash anyway.)
6073          *
6074          * It's obvious that we must do this when not WAL-logging the copy. It's
6075          * less obvious that we have to do it even if we did WAL-log the copied
6076          * pages. The reason is that since we're copying outside shared buffers, a
6077          * CHECKPOINT occurring during the copy has no way to flush the previously
6078          * written data to disk (indeed it won't know the new rel even exists).  A
6079          * crash later on would replay WAL from the checkpoint, therefore it
6080          * wouldn't replay our earlier WAL entries. If we do not fsync those pages
6081          * here, they might still not be on disk when the crash occurs.
6082          */
6083         if (!rel->rd_istemp)
6084                 smgrimmedsync(dst);
6085 }
6086
6087 /*
6088  * ALTER TABLE ENABLE/DISABLE TRIGGER
6089  *
6090  * We just pass this off to trigger.c.
6091  */
6092 static void
6093 ATExecEnableDisableTrigger(Relation rel, char *trigname,
6094                                                    bool enable, bool skip_system)
6095 {
6096         EnableDisableTrigger(rel, trigname, enable, skip_system);
6097 }
6098
6099 /*
6100  * ALTER TABLE INHERIT
6101  *
6102  * Add a parent to the child's parents. This verifies that all the columns and
6103  * check constraints of the parent appear in the child and that they have the
6104  * same data types and expressions.
6105  */
6106 static void
6107 ATExecAddInherit(Relation child_rel, RangeVar *parent)
6108 {
6109         Relation        parent_rel,
6110                                 catalogRelation;
6111         SysScanDesc scan;
6112         ScanKeyData key;
6113         HeapTuple       inheritsTuple;
6114         int32           inhseqno;
6115         List       *children;
6116
6117         /*
6118          * AccessShareLock on the parent is what's obtained during normal CREATE
6119          * TABLE ... INHERITS ..., so should be enough here.
6120          */
6121         parent_rel = heap_openrv(parent, AccessShareLock);
6122
6123         /*
6124          * Must be owner of both parent and child -- child was checked by
6125          * ATSimplePermissions call in ATPrepCmd
6126          */
6127         ATSimplePermissions(parent_rel, false);
6128
6129         /* Permanent rels cannot inherit from temporary ones */
6130         if (!isTempNamespace(RelationGetNamespace(child_rel)) &&
6131                 isTempNamespace(RelationGetNamespace(parent_rel)))
6132                 ereport(ERROR,
6133                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6134                                  errmsg("cannot inherit from temporary relation \"%s\"",
6135                                                 RelationGetRelationName(parent_rel))));
6136
6137         /*
6138          * Check for duplicates in the list of parents, and determine the highest
6139          * inhseqno already present; we'll use the next one for the new parent.
6140          * (Note: get RowExclusiveLock because we will write pg_inherits below.)
6141          *
6142          * Note: we do not reject the case where the child already inherits from
6143          * the parent indirectly; CREATE TABLE doesn't reject comparable cases.
6144          */
6145         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
6146         ScanKeyInit(&key,
6147                                 Anum_pg_inherits_inhrelid,
6148                                 BTEqualStrategyNumber, F_OIDEQ,
6149                                 ObjectIdGetDatum(RelationGetRelid(child_rel)));
6150         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
6151                                                           true, SnapshotNow, 1, &key);
6152
6153         /* inhseqno sequences start at 1 */
6154         inhseqno = 0;
6155         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
6156         {
6157                 Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inheritsTuple);
6158
6159                 if (inh->inhparent == RelationGetRelid(parent_rel))
6160                         ereport(ERROR,
6161                                         (errcode(ERRCODE_DUPLICATE_TABLE),
6162                                          errmsg("inherited relation \"%s\" duplicated",
6163                                                         RelationGetRelationName(parent_rel))));
6164                 if (inh->inhseqno > inhseqno)
6165                         inhseqno = inh->inhseqno;
6166         }
6167         systable_endscan(scan);
6168
6169         /*
6170          * Prevent circularity by seeing if proposed parent inherits from child.
6171          * (In particular, this disallows making a rel inherit from itself.)
6172          *
6173          * This is not completely bulletproof because of race conditions: in
6174          * multi-level inheritance trees, someone else could concurrently
6175          * be making another inheritance link that closes the loop but does
6176          * not join either of the rels we have locked.  Preventing that seems
6177          * to require exclusive locks on the entire inheritance tree, which is
6178          * a cure worse than the disease.  find_all_inheritors() will cope with
6179          * circularity anyway, so don't sweat it too much.
6180          */
6181         children = find_all_inheritors(RelationGetRelid(child_rel));
6182
6183         if (list_member_oid(children, RelationGetRelid(parent_rel)))
6184                 ereport(ERROR,
6185                                 (errcode(ERRCODE_DUPLICATE_TABLE),
6186                                  errmsg("circular inheritance not allowed"),
6187                                  errdetail("\"%s\" is already a child of \"%s\".",
6188                                                    parent->relname,
6189                                                    RelationGetRelationName(child_rel))));
6190
6191         /* If parent has OIDs then child must have OIDs */
6192         if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
6193                 ereport(ERROR,
6194                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6195                                  errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
6196                                                 RelationGetRelationName(child_rel),
6197                                                 RelationGetRelationName(parent_rel))));
6198
6199         /* Match up the columns and bump attinhcount and attislocal */
6200         MergeAttributesIntoExisting(child_rel, parent_rel);
6201
6202         /* Match up the constraints and make sure they're present in child */
6203         MergeConstraintsIntoExisting(child_rel, parent_rel);
6204
6205         /*
6206          * OK, it looks valid.  Make the catalog entries that show inheritance.
6207          */
6208         StoreCatalogInheritance1(RelationGetRelid(child_rel),
6209                                                          RelationGetRelid(parent_rel),
6210                                                          inhseqno + 1,
6211                                                          catalogRelation);
6212
6213         /* Now we're done with pg_inherits */
6214         heap_close(catalogRelation, RowExclusiveLock);
6215
6216         /* keep our lock on the parent relation until commit */
6217         heap_close(parent_rel, NoLock);
6218 }
6219
6220 /*
6221  * Obtain the source-text form of the constraint expression for a check
6222  * constraint, given its pg_constraint tuple
6223  */
6224 static char *
6225 decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
6226 {
6227         Form_pg_constraint con;
6228         bool            isnull;
6229         Datum           attr;
6230         Datum           expr;
6231
6232         con = (Form_pg_constraint) GETSTRUCT(contup);
6233         attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
6234         if (isnull)
6235                 elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));
6236
6237         expr = DirectFunctionCall2(pg_get_expr, attr,
6238                                                            ObjectIdGetDatum(con->conrelid));
6239         return DatumGetCString(DirectFunctionCall1(textout, expr));
6240 }
6241
6242 /*
6243  * Check columns in child table match up with columns in parent, and increment
6244  * their attinhcount.
6245  *
6246  * Called by ATExecAddInherit
6247  *
6248  * Currently all parent columns must be found in child. Missing columns are an
6249  * error.  One day we might consider creating new columns like CREATE TABLE
6250  * does.  However, that is widely unpopular --- in the common use case of
6251  * partitioned tables it's a foot-gun.
6252  *
6253  * The data type must match exactly. If the parent column is NOT NULL then
6254  * the child must be as well. Defaults are not compared, however.
6255  */
6256 static void
6257 MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
6258 {
6259         Relation        attrrel;
6260         AttrNumber      parent_attno;
6261         int                     parent_natts;
6262         TupleDesc       tupleDesc;
6263         TupleConstr *constr;
6264         HeapTuple       tuple;
6265
6266         attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
6267
6268         tupleDesc = RelationGetDescr(parent_rel);
6269         parent_natts = tupleDesc->natts;
6270         constr = tupleDesc->constr;
6271
6272         for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
6273         {
6274                 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
6275                 char       *attributeName = NameStr(attribute->attname);
6276
6277                 /* Ignore dropped columns in the parent. */
6278                 if (attribute->attisdropped)
6279                         continue;
6280
6281                 /* Find same column in child (matching on column name). */
6282                 tuple = SearchSysCacheCopyAttName(RelationGetRelid(child_rel),
6283                                                                                   attributeName);
6284                 if (HeapTupleIsValid(tuple))
6285                 {
6286                         /* Check they are same type and typmod */
6287                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
6288
6289                         if (attribute->atttypid != childatt->atttypid ||
6290                                 attribute->atttypmod != childatt->atttypmod)
6291                                 ereport(ERROR,
6292                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
6293                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
6294                                                                 RelationGetRelationName(child_rel),
6295                                                                 attributeName)));
6296
6297                         if (attribute->attnotnull && !childatt->attnotnull)
6298                                 ereport(ERROR,
6299                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
6300                                           errmsg("column \"%s\" in child table must be marked NOT NULL",
6301                                                          attributeName)));
6302
6303                         /*
6304                          * OK, bump the child column's inheritance count.  (If we fail
6305                          * later on, this change will just roll back.)
6306                          */
6307                         childatt->attinhcount++;
6308                         simple_heap_update(attrrel, &tuple->t_self, tuple);
6309                         CatalogUpdateIndexes(attrrel, tuple);
6310                         heap_freetuple(tuple);
6311                 }
6312                 else
6313                 {
6314                         ereport(ERROR,
6315                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6316                                          errmsg("child table is missing column \"%s\"",
6317                                                         attributeName)));
6318                 }
6319         }
6320
6321         heap_close(attrrel, RowExclusiveLock);
6322 }
6323
6324 /*
6325  * Check constraints in child table match up with constraints in parent
6326  *
6327  * Called by ATExecAddInherit
6328  *
6329  * Currently all constraints in parent must be present in the child. One day we
6330  * may consider adding new constraints like CREATE TABLE does. We may also want
6331  * to allow an optional flag on parent table constraints indicating they are
6332  * intended to ONLY apply to the master table, not to the children. That would
6333  * make it possible to ensure no records are mistakenly inserted into the
6334  * master in partitioned tables rather than the appropriate child.
6335  *
6336  * XXX This is O(N^2) which may be an issue with tables with hundreds of
6337  * constraints. As long as tables have more like 10 constraints it shouldn't be
6338  * a problem though. Even 100 constraints ought not be the end of the world.
6339  */
6340 static void
6341 MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
6342 {
6343         Relation        catalogRelation;
6344         TupleDesc       tupleDesc;
6345         SysScanDesc scan;
6346         ScanKeyData key;
6347         HeapTuple       constraintTuple;
6348         ListCell   *elem;
6349         List       *constraints;
6350
6351         /* First gather up the child's constraint definitions */
6352         catalogRelation = heap_open(ConstraintRelationId, AccessShareLock);
6353         tupleDesc = RelationGetDescr(catalogRelation);
6354
6355         ScanKeyInit(&key,
6356                                 Anum_pg_constraint_conrelid,
6357                                 BTEqualStrategyNumber, F_OIDEQ,
6358                                 ObjectIdGetDatum(RelationGetRelid(child_rel)));
6359         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
6360                                                           true, SnapshotNow, 1, &key);
6361
6362         constraints = NIL;
6363         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
6364         {
6365                 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
6366
6367                 if (con->contype != CONSTRAINT_CHECK)
6368                         continue;
6369
6370                 constraints = lappend(constraints, heap_copytuple(constraintTuple));
6371         }
6372
6373         systable_endscan(scan);
6374
6375         /* Then scan through the parent's constraints looking for matches */
6376         ScanKeyInit(&key,
6377                                 Anum_pg_constraint_conrelid,
6378                                 BTEqualStrategyNumber, F_OIDEQ,
6379                                 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
6380         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId, true,
6381                                                           SnapshotNow, 1, &key);
6382
6383         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
6384         {
6385                 Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
6386                 bool            found = false;
6387                 Form_pg_constraint child_con = NULL;
6388                 HeapTuple       child_contuple = NULL;
6389
6390                 if (parent_con->contype != CONSTRAINT_CHECK)
6391                         continue;
6392
6393                 foreach(elem, constraints)
6394                 {
6395                         child_contuple = (HeapTuple) lfirst(elem);
6396                         child_con = (Form_pg_constraint) GETSTRUCT(child_contuple);
6397                         if (strcmp(NameStr(parent_con->conname),
6398                                            NameStr(child_con->conname)) == 0)
6399                         {
6400                                 found = true;
6401                                 break;
6402                         }
6403                 }
6404
6405                 if (!found)
6406                         ereport(ERROR,
6407                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6408                                          errmsg("child table is missing constraint \"%s\"",
6409                                                         NameStr(parent_con->conname))));
6410
6411                 if (parent_con->condeferrable != child_con->condeferrable ||
6412                         parent_con->condeferred != child_con->condeferred ||
6413                         strcmp(decompile_conbin(constraintTuple, tupleDesc),
6414                                    decompile_conbin(child_contuple, tupleDesc)) != 0)
6415                         ereport(ERROR,
6416                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6417                                          errmsg("constraint definition for check constraint \"%s\" does not match",
6418                                                         NameStr(parent_con->conname))));
6419
6420                 /*
6421                  * TODO: add conislocal,coninhcount to constraints. This is where we
6422                  * would have to bump them just like attributes
6423                  */
6424         }
6425
6426         systable_endscan(scan);
6427         heap_close(catalogRelation, AccessShareLock);
6428 }
6429
6430 /*
6431  * ALTER TABLE NO INHERIT
6432  *
6433  * Drop a parent from the child's parents. This just adjusts the attinhcount
6434  * and attislocal of the columns and removes the pg_inherit and pg_depend
6435  * entries.
6436  *
6437  * If attinhcount goes to 0 then attislocal gets set to true. If it goes back
6438  * up attislocal stays true, which means if a child is ever removed from a
6439  * parent then its columns will never be automatically dropped which may
6440  * surprise. But at least we'll never surprise by dropping columns someone
6441  * isn't expecting to be dropped which would actually mean data loss.
6442  */
6443 static void
6444 ATExecDropInherit(Relation rel, RangeVar *parent)
6445 {
6446         Relation        parent_rel;
6447         Relation        catalogRelation;
6448         SysScanDesc scan;
6449         ScanKeyData key[3];
6450         HeapTuple       inheritsTuple,
6451                                 attributeTuple,
6452                                 depTuple;
6453         bool            found = false;
6454
6455         /*
6456          * AccessShareLock on the parent is probably enough, seeing that DROP TABLE
6457          * doesn't lock parent tables at all.  We need some lock since we'll be
6458          * inspecting the parent's schema.
6459          */
6460         parent_rel = heap_openrv(parent, AccessShareLock);
6461
6462         /*
6463          * We don't bother to check ownership of the parent table --- ownership
6464          * of the child is presumed enough rights.
6465          */
6466
6467         /*
6468          * Find and destroy the pg_inherits entry linking the two, or error out
6469          * if there is none.
6470          */
6471         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
6472         ScanKeyInit(&key[0],
6473                                 Anum_pg_inherits_inhrelid,
6474                                 BTEqualStrategyNumber, F_OIDEQ,
6475                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6476         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
6477                                                           true, SnapshotNow, 1, key);
6478
6479         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
6480         {
6481                 Oid                     inhparent;
6482
6483                 inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
6484                 if (inhparent == RelationGetRelid(parent_rel))
6485                 {
6486                         simple_heap_delete(catalogRelation, &inheritsTuple->t_self);
6487                         found = true;
6488                         break;
6489                 }
6490         }
6491
6492         systable_endscan(scan);
6493         heap_close(catalogRelation, RowExclusiveLock);
6494
6495         if (!found)
6496                 ereport(ERROR,
6497                                 (errcode(ERRCODE_UNDEFINED_TABLE),
6498                                  errmsg("relation \"%s\" is not a parent of relation \"%s\"",
6499                                                 RelationGetRelationName(parent_rel),
6500                                                 RelationGetRelationName(rel))));
6501
6502         /*
6503          * Search through child columns looking for ones matching parent rel
6504          */
6505         catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock);
6506         ScanKeyInit(&key[0],
6507                                 Anum_pg_attribute_attrelid,
6508                                 BTEqualStrategyNumber, F_OIDEQ,
6509                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6510         scan = systable_beginscan(catalogRelation, AttributeRelidNumIndexId,
6511                                                           true, SnapshotNow, 1, key);
6512         while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
6513         {
6514                 Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
6515
6516                 /* Ignore if dropped or not inherited */
6517                 if (att->attisdropped)
6518                         continue;
6519                 if (att->attinhcount <= 0)
6520                         continue;
6521
6522                 if (SearchSysCacheExistsAttName(RelationGetRelid(parent_rel),
6523                                                                                 NameStr(att->attname)))
6524                 {
6525                         /* Decrement inhcount and possibly set islocal to true */
6526                         HeapTuple       copyTuple = heap_copytuple(attributeTuple);
6527                         Form_pg_attribute copy_att = (Form_pg_attribute) GETSTRUCT(copyTuple);
6528
6529                         copy_att->attinhcount--;
6530                         if (copy_att->attinhcount == 0)
6531                                 copy_att->attislocal = true;
6532
6533                         simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
6534                         CatalogUpdateIndexes(catalogRelation, copyTuple);
6535                         heap_freetuple(copyTuple);
6536                 }
6537         }
6538         systable_endscan(scan);
6539         heap_close(catalogRelation, RowExclusiveLock);
6540
6541         /*
6542          * Drop the dependency
6543          *
6544          * There's no convenient way to do this, so go trawling through pg_depend
6545          */
6546         catalogRelation = heap_open(DependRelationId, RowExclusiveLock);
6547
6548         ScanKeyInit(&key[0],
6549                                 Anum_pg_depend_classid,
6550                                 BTEqualStrategyNumber, F_OIDEQ,
6551                                 ObjectIdGetDatum(RelationRelationId));
6552         ScanKeyInit(&key[1],
6553                                 Anum_pg_depend_objid,
6554                                 BTEqualStrategyNumber, F_OIDEQ,
6555                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6556         ScanKeyInit(&key[2],
6557                                 Anum_pg_depend_objsubid,
6558                                 BTEqualStrategyNumber, F_INT4EQ,
6559                                 Int32GetDatum(0));
6560
6561         scan = systable_beginscan(catalogRelation, DependDependerIndexId, true,
6562                                                           SnapshotNow, 3, key);
6563
6564         while (HeapTupleIsValid(depTuple = systable_getnext(scan)))
6565         {
6566                 Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(depTuple);
6567
6568                 if (dep->refclassid == RelationRelationId &&
6569                         dep->refobjid == RelationGetRelid(parent_rel) &&
6570                         dep->refobjsubid == 0 &&
6571                         dep->deptype == DEPENDENCY_NORMAL)
6572                         simple_heap_delete(catalogRelation, &depTuple->t_self);
6573         }
6574
6575         systable_endscan(scan);
6576         heap_close(catalogRelation, RowExclusiveLock);
6577
6578         /* keep our lock on the parent relation until commit */
6579         heap_close(parent_rel, NoLock);
6580 }
6581
6582
6583 /*
6584  * Execute ALTER TABLE SET SCHEMA
6585  *
6586  * Note: caller must have checked ownership of the relation already
6587  */
6588 void
6589 AlterTableNamespace(RangeVar *relation, const char *newschema)
6590 {
6591         Relation        rel;
6592         Oid                     relid;
6593         Oid                     oldNspOid;
6594         Oid                     nspOid;
6595         Relation        classRel;
6596
6597         rel = heap_openrv(relation, AccessExclusiveLock);
6598
6599         relid = RelationGetRelid(rel);
6600         oldNspOid = RelationGetNamespace(rel);
6601
6602         /* heap_openrv allows TOAST, but we don't want to */
6603         if (rel->rd_rel->relkind == RELKIND_TOASTVALUE)
6604                 ereport(ERROR,
6605                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6606                                  errmsg("\"%s\" is a TOAST relation",
6607                                                 RelationGetRelationName(rel))));
6608
6609         /* if it's an owned sequence, disallow moving it by itself */
6610         if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
6611         {
6612                 Oid                     tableId;
6613                 int32           colId;
6614
6615                 if (sequenceIsOwned(relid, &tableId, &colId))
6616                         ereport(ERROR,
6617                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6618                                  errmsg("cannot move an owned sequence into another schema"),
6619                                          errdetail("Sequence \"%s\" is linked to table \"%s\".",
6620                                                            RelationGetRelationName(rel),
6621                                                            get_rel_name(tableId))));
6622         }
6623
6624         /* get schema OID and check its permissions */
6625         nspOid = LookupCreationNamespace(newschema);
6626
6627         if (oldNspOid == nspOid)
6628                 ereport(ERROR,
6629                                 (errcode(ERRCODE_DUPLICATE_TABLE),
6630                                  errmsg("relation \"%s\" is already in schema \"%s\"",
6631                                                 RelationGetRelationName(rel),
6632                                                 newschema)));
6633
6634         /* disallow renaming into or out of temp schemas */
6635         if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
6636                 ereport(ERROR,
6637                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6638                         errmsg("cannot move objects into or out of temporary schemas")));
6639
6640         /* same for TOAST schema */
6641         if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
6642                 ereport(ERROR,
6643                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6644                                  errmsg("cannot move objects into or out of TOAST schema")));
6645
6646         /* OK, modify the pg_class row and pg_depend entry */
6647         classRel = heap_open(RelationRelationId, RowExclusiveLock);
6648
6649         AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true);
6650
6651         /* Fix the table's rowtype too */
6652         AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false);
6653
6654         /* Fix other dependent stuff */
6655         if (rel->rd_rel->relkind == RELKIND_RELATION)
6656         {
6657                 AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid);
6658                 AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid, newschema);
6659                 AlterConstraintNamespaces(relid, oldNspOid, nspOid, false);
6660         }
6661
6662         heap_close(classRel, RowExclusiveLock);
6663
6664         /* close rel, but keep lock until commit */
6665         relation_close(rel, NoLock);
6666 }
6667
6668 /*
6669  * The guts of relocating a relation to another namespace: fix the pg_class
6670  * entry, and the pg_depend entry if any.  Caller must already have
6671  * opened and write-locked pg_class.
6672  */
6673 void
6674 AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
6675                                                            Oid oldNspOid, Oid newNspOid,
6676                                                            bool hasDependEntry)
6677 {
6678         HeapTuple       classTup;
6679         Form_pg_class classForm;
6680
6681         classTup = SearchSysCacheCopy(RELOID,
6682                                                                   ObjectIdGetDatum(relOid),
6683                                                                   0, 0, 0);
6684         if (!HeapTupleIsValid(classTup))
6685                 elog(ERROR, "cache lookup failed for relation %u", relOid);
6686         classForm = (Form_pg_class) GETSTRUCT(classTup);
6687
6688         Assert(classForm->relnamespace == oldNspOid);
6689
6690         /* check for duplicate name (more friendly than unique-index failure) */
6691         if (get_relname_relid(NameStr(classForm->relname),
6692                                                   newNspOid) != InvalidOid)
6693                 ereport(ERROR,
6694                                 (errcode(ERRCODE_DUPLICATE_TABLE),
6695                                  errmsg("relation \"%s\" already exists in schema \"%s\"",
6696                                                 NameStr(classForm->relname),
6697                                                 get_namespace_name(newNspOid))));
6698
6699         /* classTup is a copy, so OK to scribble on */
6700         classForm->relnamespace = newNspOid;
6701
6702         simple_heap_update(classRel, &classTup->t_self, classTup);
6703         CatalogUpdateIndexes(classRel, classTup);
6704
6705         /* Update dependency on schema if caller said so */
6706         if (hasDependEntry &&
6707                 changeDependencyFor(RelationRelationId, relOid,
6708                                                         NamespaceRelationId, oldNspOid, newNspOid) != 1)
6709                 elog(ERROR, "failed to change schema dependency for relation \"%s\"",
6710                          NameStr(classForm->relname));
6711
6712         heap_freetuple(classTup);
6713 }
6714
6715 /*
6716  * Move all indexes for the specified relation to another namespace.
6717  *
6718  * Note: we assume adequate permission checking was done by the caller,
6719  * and that the caller has a suitable lock on the owning relation.
6720  */
6721 static void
6722 AlterIndexNamespaces(Relation classRel, Relation rel,
6723                                          Oid oldNspOid, Oid newNspOid)
6724 {
6725         List       *indexList;
6726         ListCell   *l;
6727
6728         indexList = RelationGetIndexList(rel);
6729
6730         foreach(l, indexList)
6731         {
6732                 Oid                     indexOid = lfirst_oid(l);
6733
6734                 /*
6735                  * Note: currently, the index will not have its own dependency on the
6736                  * namespace, so we don't need to do changeDependencyFor(). There's no
6737                  * rowtype in pg_type, either.
6738                  */
6739                 AlterRelationNamespaceInternal(classRel, indexOid,
6740                                                                            oldNspOid, newNspOid,
6741                                                                            false);
6742         }
6743
6744         list_free(indexList);
6745 }
6746
6747 /*
6748  * Move all SERIAL-column sequences of the specified relation to another
6749  * namespace.
6750  *
6751  * Note: we assume adequate permission checking was done by the caller,
6752  * and that the caller has a suitable lock on the owning relation.
6753  */
6754 static void
6755 AlterSeqNamespaces(Relation classRel, Relation rel,
6756                                    Oid oldNspOid, Oid newNspOid, const char *newNspName)
6757 {
6758         Relation        depRel;
6759         SysScanDesc scan;
6760         ScanKeyData key[2];
6761         HeapTuple       tup;
6762
6763         /*
6764          * SERIAL sequences are those having an auto dependency on one of the
6765          * table's columns (we don't care *which* column, exactly).
6766          */
6767         depRel = heap_open(DependRelationId, AccessShareLock);
6768
6769         ScanKeyInit(&key[0],
6770                                 Anum_pg_depend_refclassid,
6771                                 BTEqualStrategyNumber, F_OIDEQ,
6772                                 ObjectIdGetDatum(RelationRelationId));
6773         ScanKeyInit(&key[1],
6774                                 Anum_pg_depend_refobjid,
6775                                 BTEqualStrategyNumber, F_OIDEQ,
6776                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6777         /* we leave refobjsubid unspecified */
6778
6779         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
6780                                                           SnapshotNow, 2, key);
6781
6782         while (HeapTupleIsValid(tup = systable_getnext(scan)))
6783         {
6784                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
6785                 Relation        seqRel;
6786
6787                 /* skip dependencies other than auto dependencies on columns */
6788                 if (depForm->refobjsubid == 0 ||
6789                         depForm->classid != RelationRelationId ||
6790                         depForm->objsubid != 0 ||
6791                         depForm->deptype != DEPENDENCY_AUTO)
6792                         continue;
6793
6794                 /* Use relation_open just in case it's an index */
6795                 seqRel = relation_open(depForm->objid, AccessExclusiveLock);
6796
6797                 /* skip non-sequence relations */
6798                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
6799                 {
6800                         /* No need to keep the lock */
6801                         relation_close(seqRel, AccessExclusiveLock);
6802                         continue;
6803                 }
6804
6805                 /* Fix the pg_class and pg_depend entries */
6806                 AlterRelationNamespaceInternal(classRel, depForm->objid,
6807                                                                            oldNspOid, newNspOid,
6808                                                                            true);
6809
6810                 /*
6811                  * Sequences have entries in pg_type. We need to be careful to move
6812                  * them to the new namespace, too.
6813                  */
6814                 AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
6815                                                                    newNspOid, false);
6816
6817                 /* Now we can close it.  Keep the lock till end of transaction. */
6818                 relation_close(seqRel, NoLock);
6819         }
6820
6821         systable_endscan(scan);
6822
6823         relation_close(depRel, AccessShareLock);
6824 }
6825
6826
6827 /*
6828  * This code supports
6829  *      CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
6830  *
6831  * Because we only support this for TEMP tables, it's sufficient to remember
6832  * the state in a backend-local data structure.
6833  */
6834
6835 /*
6836  * Register a newly-created relation's ON COMMIT action.
6837  */
6838 void
6839 register_on_commit_action(Oid relid, OnCommitAction action)
6840 {
6841         OnCommitItem *oc;
6842         MemoryContext oldcxt;
6843
6844         /*
6845          * We needn't bother registering the relation unless there is an ON COMMIT
6846          * action we need to take.
6847          */
6848         if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
6849                 return;
6850
6851         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
6852
6853         oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
6854         oc->relid = relid;
6855         oc->oncommit = action;
6856         oc->creating_subid = GetCurrentSubTransactionId();
6857         oc->deleting_subid = InvalidSubTransactionId;
6858
6859         on_commits = lcons(oc, on_commits);
6860
6861         MemoryContextSwitchTo(oldcxt);
6862 }
6863
6864 /*
6865  * Unregister any ON COMMIT action when a relation is deleted.
6866  *
6867  * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
6868  */
6869 void
6870 remove_on_commit_action(Oid relid)
6871 {
6872         ListCell   *l;
6873
6874         foreach(l, on_commits)
6875         {
6876                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
6877
6878                 if (oc->relid == relid)
6879                 {
6880                         oc->deleting_subid = GetCurrentSubTransactionId();
6881                         break;
6882                 }
6883         }
6884 }
6885
6886 /*
6887  * Perform ON COMMIT actions.
6888  *
6889  * This is invoked just before actually committing, since it's possible
6890  * to encounter errors.
6891  */
6892 void
6893 PreCommit_on_commit_actions(void)
6894 {
6895         ListCell   *l;
6896         List       *oids_to_truncate = NIL;
6897
6898         foreach(l, on_commits)
6899         {
6900                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
6901
6902                 /* Ignore entry if already dropped in this xact */
6903                 if (oc->deleting_subid != InvalidSubTransactionId)
6904                         continue;
6905
6906                 switch (oc->oncommit)
6907                 {
6908                         case ONCOMMIT_NOOP:
6909                         case ONCOMMIT_PRESERVE_ROWS:
6910                                 /* Do nothing (there shouldn't be such entries, actually) */
6911                                 break;
6912                         case ONCOMMIT_DELETE_ROWS:
6913                                 oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
6914                                 break;
6915                         case ONCOMMIT_DROP:
6916                                 {
6917                                         ObjectAddress object;
6918
6919                                         object.classId = RelationRelationId;
6920                                         object.objectId = oc->relid;
6921                                         object.objectSubId = 0;
6922                                         performDeletion(&object, DROP_CASCADE);
6923
6924                                         /*
6925                                          * Note that table deletion will call
6926                                          * remove_on_commit_action, so the entry should get marked
6927                                          * as deleted.
6928                                          */
6929                                         Assert(oc->deleting_subid != InvalidSubTransactionId);
6930                                         break;
6931                                 }
6932                 }
6933         }
6934         if (oids_to_truncate != NIL)
6935         {
6936                 heap_truncate(oids_to_truncate);
6937                 CommandCounterIncrement();              /* XXX needed? */
6938         }
6939 }
6940
6941 /*
6942  * Post-commit or post-abort cleanup for ON COMMIT management.
6943  *
6944  * All we do here is remove no-longer-needed OnCommitItem entries.
6945  *
6946  * During commit, remove entries that were deleted during this transaction;
6947  * during abort, remove those created during this transaction.
6948  */
6949 void
6950 AtEOXact_on_commit_actions(bool isCommit)
6951 {
6952         ListCell   *cur_item;
6953         ListCell   *prev_item;
6954
6955         prev_item = NULL;
6956         cur_item = list_head(on_commits);
6957
6958         while (cur_item != NULL)
6959         {
6960                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
6961
6962                 if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
6963                         oc->creating_subid != InvalidSubTransactionId)
6964                 {
6965                         /* cur_item must be removed */
6966                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
6967                         pfree(oc);
6968                         if (prev_item)
6969                                 cur_item = lnext(prev_item);
6970                         else
6971                                 cur_item = list_head(on_commits);
6972                 }
6973                 else
6974                 {
6975                         /* cur_item must be preserved */
6976                         oc->creating_subid = InvalidSubTransactionId;
6977                         oc->deleting_subid = InvalidSubTransactionId;
6978                         prev_item = cur_item;
6979                         cur_item = lnext(prev_item);
6980                 }
6981         }
6982 }
6983
6984 /*
6985  * Post-subcommit or post-subabort cleanup for ON COMMIT management.
6986  *
6987  * During subabort, we can immediately remove entries created during this
6988  * subtransaction.      During subcommit, just relabel entries marked during
6989  * this subtransaction as being the parent's responsibility.
6990  */
6991 void
6992 AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
6993                                                           SubTransactionId parentSubid)
6994 {
6995         ListCell   *cur_item;
6996         ListCell   *prev_item;
6997
6998         prev_item = NULL;
6999         cur_item = list_head(on_commits);
7000
7001         while (cur_item != NULL)
7002         {
7003                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
7004
7005                 if (!isCommit && oc->creating_subid == mySubid)
7006                 {
7007                         /* cur_item must be removed */
7008                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
7009                         pfree(oc);
7010                         if (prev_item)
7011                                 cur_item = lnext(prev_item);
7012                         else
7013                                 cur_item = list_head(on_commits);
7014                 }
7015                 else
7016                 {
7017                         /* cur_item must be preserved */
7018                         if (oc->creating_subid == mySubid)
7019                                 oc->creating_subid = parentSubid;
7020                         if (oc->deleting_subid == mySubid)
7021                                 oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
7022                         prev_item = cur_item;
7023                         cur_item = lnext(prev_item);
7024                 }
7025         }
7026 }