1 /*-------------------------------------------------------------------------
4 * Commands for creating and altering table structures and settings
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.159 2005/05/30 07:20:58 neilc Exp $
13 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/tuptoaster.h"
19 #include "catalog/catalog.h"
20 #include "catalog/dependency.h"
21 #include "catalog/heap.h"
22 #include "catalog/index.h"
23 #include "catalog/indexing.h"
24 #include "catalog/namespace.h"
25 #include "catalog/pg_constraint.h"
26 #include "catalog/pg_depend.h"
27 #include "catalog/pg_inherits.h"
28 #include "catalog/pg_namespace.h"
29 #include "catalog/pg_opclass.h"
30 #include "catalog/pg_trigger.h"
31 #include "catalog/pg_type.h"
32 #include "commands/cluster.h"
33 #include "commands/defrem.h"
34 #include "commands/tablecmds.h"
35 #include "commands/tablespace.h"
36 #include "commands/trigger.h"
37 #include "commands/typecmds.h"
38 #include "executor/executor.h"
39 #include "lib/stringinfo.h"
40 #include "miscadmin.h"
41 #include "nodes/makefuncs.h"
42 #include "optimizer/clauses.h"
43 #include "optimizer/plancat.h"
44 #include "optimizer/prep.h"
45 #include "parser/analyze.h"
46 #include "parser/gramparse.h"
47 #include "parser/parser.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 "rewrite/rewriteHandler.h"
55 #include "storage/smgr.h"
56 #include "utils/acl.h"
57 #include "utils/builtins.h"
58 #include "utils/fmgroids.h"
59 #include "utils/inval.h"
60 #include "utils/lsyscache.h"
61 #include "utils/memutils.h"
62 #include "utils/relcache.h"
63 #include "utils/syscache.h"
67 * ON COMMIT action list
69 typedef struct OnCommitItem
71 Oid relid; /* relid of relation */
72 OnCommitAction oncommit; /* what to do at end of xact */
75 * If this entry was created during the current transaction,
76 * creating_subid is the ID of the creating subxact; if created in a prior
77 * transaction, creating_subid is zero. If deleted during the current
78 * transaction, deleting_subid is the ID of the deleting subxact; if no
79 * deletion request is pending, deleting_subid is zero.
81 SubTransactionId creating_subid;
82 SubTransactionId deleting_subid;
85 static List *on_commits = NIL;
89 * State information for ALTER TABLE
91 * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
92 * structs, one for each table modified by the operation (the named table
93 * plus any child tables that are affected). We save lists of subcommands
94 * to apply to this table (possibly modified by parse transformation steps);
95 * these lists will be executed in Phase 2. If a Phase 3 step is needed,
96 * necessary information is stored in the constraints and newvals lists.
98 * Phase 2 is divided into multiple passes; subcommands are executed in
99 * a pass determined by subcommand type.
102 #define AT_PASS_DROP 0 /* DROP (all flavors) */
103 #define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */
104 #define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */
105 #define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints */
106 #define AT_PASS_COL_ATTRS 4 /* set other column attributes */
107 /* We could support a RENAME COLUMN pass here, but not currently used */
108 #define AT_PASS_ADD_COL 5 /* ADD COLUMN */
109 #define AT_PASS_ADD_INDEX 6 /* ADD indexes */
110 #define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */
111 #define AT_PASS_MISC 8 /* other stuff */
112 #define AT_NUM_PASSES 9
114 typedef struct AlteredTableInfo
116 /* Information saved before any work commences: */
117 Oid relid; /* Relation to work on */
118 char relkind; /* Its relkind */
119 TupleDesc oldDesc; /* Pre-modification tuple descriptor */
120 /* Information saved by Phase 1 for Phase 2: */
121 List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
122 /* Information saved by Phases 1/2 for Phase 3: */
123 List *constraints; /* List of NewConstraint */
124 List *newvals; /* List of NewColumnValue */
125 Oid newTableSpace; /* new tablespace; 0 means no change */
126 /* Objects to rebuild after completing ALTER TYPE operations */
127 List *changedConstraintOids; /* OIDs of constraints to rebuild */
128 List *changedConstraintDefs; /* string definitions of same */
129 List *changedIndexOids; /* OIDs of indexes to rebuild */
130 List *changedIndexDefs; /* string definitions of same */
133 /* Struct describing one new constraint to check in Phase 3 scan */
134 typedef struct NewConstraint
136 char *name; /* Constraint name, or NULL if none */
137 ConstrType contype; /* CHECK, NOT_NULL, or FOREIGN */
138 AttrNumber attnum; /* only relevant for NOT_NULL */
139 Oid refrelid; /* PK rel, if FOREIGN */
140 Node *qual; /* Check expr or FkConstraint struct */
141 List *qualstate; /* Execution state for CHECK */
145 * Struct describing one new column value that needs to be computed during
146 * Phase 3 copy (this could be either a new column with a non-null default, or
147 * a column that we're changing the type of). Columns without such an entry
148 * are just copied from the old table during ATRewriteTable. Note that the
149 * expr is an expression over *old* table values.
151 typedef struct NewColumnValue
153 AttrNumber attnum; /* which column */
154 Expr *expr; /* expression to compute */
155 ExprState *exprstate; /* execution state */
159 static List *MergeAttributes(List *schema, List *supers, bool istemp,
160 List **supOids, List **supconstr, int *supOidCount);
161 static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
162 static void StoreCatalogInheritance(Oid relationId, List *supers);
163 static int findAttrByName(const char *attributeName, List *schema);
164 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
165 static bool needs_toast_table(Relation rel);
166 static int transformColumnNameList(Oid relId, List *colList,
167 int16 *attnums, Oid *atttypids);
168 static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
170 int16 *attnums, Oid *atttypids,
172 static Oid transformFkeyCheckAttrs(Relation pkrel,
173 int numattrs, int16 *attnums,
175 static void validateForeignKeyConstraint(FkConstraint *fkconstraint,
176 Relation rel, Relation pkrel);
177 static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
179 static char *fkMatchTypeToString(char match_type);
180 static void ATController(Relation rel, List *cmds, bool recurse);
181 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
182 bool recurse, bool recursing);
183 static void ATRewriteCatalogs(List **wqueue);
184 static void ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd);
185 static void ATRewriteTables(List **wqueue);
186 static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap);
187 static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
188 static void ATSimplePermissions(Relation rel, bool allowView);
189 static void ATSimpleRecursion(List **wqueue, Relation rel,
190 AlterTableCmd *cmd, bool recurse);
191 static void ATOneLevelRecursion(List **wqueue, Relation rel,
193 static void find_composite_type_dependencies(Oid typeOid,
194 const char *origTblName);
195 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
197 static void ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
199 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
200 static void add_column_support_dependency(Oid relid, int32 attnum,
202 static void ATExecDropNotNull(Relation rel, const char *colName);
203 static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
204 const char *colName);
205 static void ATExecColumnDefault(Relation rel, const char *colName,
207 static void ATPrepSetStatistics(Relation rel, const char *colName,
209 static void ATExecSetStatistics(Relation rel, const char *colName,
211 static void ATExecSetStorage(Relation rel, const char *colName,
213 static void ATExecDropColumn(Relation rel, const char *colName,
214 DropBehavior behavior,
215 bool recurse, bool recursing);
216 static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
217 IndexStmt *stmt, bool is_rebuild);
218 static void ATExecAddConstraint(AlteredTableInfo *tab, Relation rel,
219 Node *newConstraint);
220 static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
221 FkConstraint *fkconstraint);
222 static void ATPrepDropConstraint(List **wqueue, Relation rel,
223 bool recurse, AlterTableCmd *cmd);
224 static void ATExecDropConstraint(Relation rel, const char *constrName,
225 DropBehavior behavior, bool quiet);
226 static void ATPrepAlterColumnType(List **wqueue,
227 AlteredTableInfo *tab, Relation rel,
228 bool recurse, bool recursing,
230 static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
231 const char *colName, TypeName *typename);
232 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
233 static void ATPostAlterTypeParse(char *cmd, List **wqueue);
234 static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
235 static void change_owner_recurse_to_sequences(Oid relationOid,
236 int32 newOwnerSysId);
237 static void ATExecClusterOn(Relation rel, const char *indexName);
238 static void ATExecDropCluster(Relation rel);
239 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
240 char *tablespacename);
241 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace);
242 static void copy_relation_data(Relation rel, SMgrRelation dst);
243 static void update_ri_trigger_args(Oid relid,
247 bool update_relname);
250 /* ----------------------------------------------------------------
252 * Creates a new relation.
254 * If successful, returns the OID of the new relation.
255 * ----------------------------------------------------------------
258 DefineRelation(CreateStmt *stmt, char relkind)
260 char relname[NAMEDATALEN];
262 List *schema = stmt->tableElts;
266 TupleDesc descriptor;
268 List *old_constraints;
277 * Truncate relname to appropriate length (probably a waste of time,
278 * as parser should have done this already).
280 StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
283 * Check consistency of arguments
285 if (stmt->oncommit != ONCOMMIT_NOOP && !stmt->relation->istemp)
287 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
288 errmsg("ON COMMIT can only be used on temporary tables")));
291 * Look up the namespace in which we are supposed to create the
292 * relation. Check we have permission to create there. Skip check if
293 * bootstrapping, since permissions machinery may not be working yet.
295 namespaceId = RangeVarGetCreationNamespace(stmt->relation);
297 if (!IsBootstrapProcessingMode())
301 aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
303 if (aclresult != ACLCHECK_OK)
304 aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
305 get_namespace_name(namespaceId));
309 * Select tablespace to use. If not specified, use default_tablespace
310 * (which may in turn default to database's default).
312 if (stmt->tablespacename)
314 tablespaceId = get_tablespace_oid(stmt->tablespacename);
315 if (!OidIsValid(tablespaceId))
317 (errcode(ERRCODE_UNDEFINED_OBJECT),
318 errmsg("tablespace \"%s\" does not exist",
319 stmt->tablespacename)));
323 tablespaceId = GetDefaultTablespace();
324 /* note InvalidOid is OK in this case */
327 /* Check permissions except when using database's default */
328 if (OidIsValid(tablespaceId))
332 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
334 if (aclresult != ACLCHECK_OK)
335 aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
336 get_tablespace_name(tablespaceId));
340 * Look up inheritance ancestors and generate relation schema,
341 * including inherited attributes.
343 schema = MergeAttributes(schema, stmt->inhRelations,
344 stmt->relation->istemp,
345 &inheritOids, &old_constraints, &parentOidCount);
348 * Create a relation descriptor from the relation schema and create
349 * the relation. Note that in this stage only inherited (pre-cooked)
350 * defaults and constraints will be included into the new relation.
351 * (BuildDescForRelation takes care of the inherited defaults, but we
352 * have to copy inherited constraints here.)
354 descriptor = BuildDescForRelation(schema);
356 localHasOids = interpretOidsOption(stmt->hasoids);
357 descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
359 if (old_constraints != NIL)
361 ConstrCheck *check = (ConstrCheck *)
362 palloc0(list_length(old_constraints) * sizeof(ConstrCheck));
365 foreach(listptr, old_constraints)
367 Constraint *cdef = (Constraint *) lfirst(listptr);
370 if (cdef->contype != CONSTR_CHECK)
372 Assert(cdef->name != NULL);
373 Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL);
376 * In multiple-inheritance situations, it's possible to
377 * inherit the same grandparent constraint through multiple
378 * parents. Hence, discard inherited constraints that match as
379 * to both name and expression. Otherwise, gripe if the names
382 for (i = 0; i < ncheck; i++)
384 if (strcmp(check[i].ccname, cdef->name) != 0)
386 if (strcmp(check[i].ccbin, cdef->cooked_expr) == 0)
392 (errcode(ERRCODE_DUPLICATE_OBJECT),
393 errmsg("duplicate check constraint name \"%s\"",
398 check[ncheck].ccname = cdef->name;
399 check[ncheck].ccbin = pstrdup(cdef->cooked_expr);
405 if (descriptor->constr == NULL)
407 descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
408 descriptor->constr->defval = NULL;
409 descriptor->constr->num_defval = 0;
410 descriptor->constr->has_not_null = false;
412 descriptor->constr->num_check = ncheck;
413 descriptor->constr->check = check;
417 relationId = heap_create_with_catalog(relname,
427 allowSystemTableMods);
429 StoreCatalogInheritance(relationId, inheritOids);
432 * We must bump the command counter to make the newly-created relation
433 * tuple visible for opening.
435 CommandCounterIncrement();
438 * Open the new relation and acquire exclusive lock on it. This isn't
439 * really necessary for locking out other backends (since they can't
440 * see the new rel anyway until we commit), but it keeps the lock
441 * manager from complaining about deadlock risks.
443 rel = relation_open(relationId, AccessExclusiveLock);
446 * Now add any newly specified column default values and CHECK
447 * constraints to the new relation. These are passed to us in the
448 * form of raw parsetrees; we need to transform them to executable
449 * expression trees before they can be added. The most convenient way
450 * to do that is to apply the parser's transformExpr routine, but
451 * transformExpr doesn't work unless we have a pre-existing relation.
452 * So, the transformation has to be postponed to this final step of
455 * Another task that's conveniently done at this step is to add
456 * dependency links between columns and supporting relations (such as
459 * First, scan schema to find new column defaults.
464 foreach(listptr, schema)
466 ColumnDef *colDef = lfirst(listptr);
470 if (colDef->raw_default != NULL)
472 RawColumnDefault *rawEnt;
474 Assert(colDef->cooked_default == NULL);
476 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
477 rawEnt->attnum = attnum;
478 rawEnt->raw_default = colDef->raw_default;
479 rawDefaults = lappend(rawDefaults, rawEnt);
482 /* Create dependency for supporting relation for this column */
483 if (colDef->support != NULL)
484 add_column_support_dependency(relationId, attnum, colDef->support);
488 * Parse and add the defaults/constraints, if any.
490 if (rawDefaults || stmt->constraints)
491 AddRelationRawConstraints(rel, rawDefaults, stmt->constraints);
494 * Clean up. We keep lock on new relation (although it shouldn't be
495 * visible to anyone else anyway, until commit).
497 relation_close(rel, NoLock);
504 * Deletes a relation.
507 RemoveRelation(const RangeVar *relation, DropBehavior behavior)
510 ObjectAddress object;
512 relOid = RangeVarGetRelid(relation, false);
514 object.classId = RelationRelationId;
515 object.objectId = relOid;
516 object.objectSubId = 0;
518 performDeletion(&object, behavior);
523 * Executes a TRUNCATE command.
525 * This is a multi-relation truncate. It first opens and grabs exclusive
526 * locks on all relations involved, checking permissions and otherwise
527 * verifying that the relation is OK for truncation. When they are all
528 * open, it checks foreign key references on them, namely that FK references
529 * are all internal to the group that's being truncated. Finally all
530 * relations are truncated and reindexed.
533 ExecuteTruncate(List *relations)
538 foreach(cell, relations)
540 RangeVar *rv = lfirst(cell);
543 /* Grab exclusive lock in preparation for truncate */
544 rel = heap_openrv(rv, AccessExclusiveLock);
546 /* Only allow truncate on regular tables */
547 if (rel->rd_rel->relkind != RELKIND_RELATION)
549 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
550 errmsg("\"%s\" is not a table",
551 RelationGetRelationName(rel))));
553 /* Permissions checks */
554 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
555 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
556 RelationGetRelationName(rel));
558 if (!allowSystemTableMods && IsSystemRelation(rel))
560 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
561 errmsg("permission denied: \"%s\" is a system catalog",
562 RelationGetRelationName(rel))));
565 * We can never allow truncation of shared or nailed-in-cache
566 * relations, because we can't support changing their relfilenode
569 if (rel->rd_rel->relisshared || rel->rd_isnailed)
571 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
572 errmsg("cannot truncate system relation \"%s\"",
573 RelationGetRelationName(rel))));
576 * Don't allow truncate on temp tables of other backends ... their
577 * local buffer manager is not going to cope.
579 if (isOtherTempNamespace(RelationGetNamespace(rel)))
581 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
582 errmsg("cannot truncate temporary tables of other sessions")));
584 /* Save it into the list of rels to truncate */
585 rels = lappend(rels, rel);
589 * Check foreign key references.
591 heap_truncate_check_FKs(rels, false);
594 * OK, truncate each table.
598 Relation rel = lfirst(cell);
603 * Create a new empty storage file for the relation, and assign it as
604 * the relfilenode value. The old storage file is scheduled for
605 * deletion at commit.
607 setNewRelfilenode(rel);
609 heap_relid = RelationGetRelid(rel);
610 toast_relid = rel->rd_rel->reltoastrelid;
612 heap_close(rel, NoLock);
615 * The same for the toast table, if any.
617 if (OidIsValid(toast_relid))
619 rel = relation_open(toast_relid, AccessExclusiveLock);
620 setNewRelfilenode(rel);
621 heap_close(rel, NoLock);
625 * Reconstruct the indexes to match, and we're done.
627 reindex_relation(heap_relid, true);
633 * Returns new schema given initial schema and superclasses.
636 * 'schema' is the column/attribute definition for the table. (It's a list
637 * of ColumnDef's.) It is destructively changed.
638 * 'supers' is a list of names (as RangeVar nodes) of parent relations.
639 * 'istemp' is TRUE if we are creating a temp relation.
642 * 'supOids' receives a list of the OIDs of the parent relations.
643 * 'supconstr' receives a list of constraints belonging to the parents,
644 * updated as necessary to be valid for the child.
645 * 'supOidCount' is set to the number of parents that have OID columns.
648 * Completed schema list.
651 * The order in which the attributes are inherited is very important.
652 * Intuitively, the inherited attributes should come first. If a table
653 * inherits from multiple parents, the order of those attributes are
654 * according to the order of the parents specified in CREATE TABLE.
658 * create table person (name text, age int4, location point);
659 * create table emp (salary int4, manager text) inherits(person);
660 * create table student (gpa float8) inherits (person);
661 * create table stud_emp (percent int4) inherits (emp, student);
663 * The order of the attributes of stud_emp is:
665 * person {1:name, 2:age, 3:location}
667 * {6:gpa} student emp {4:salary, 5:manager}
669 * stud_emp {7:percent}
671 * If the same attribute name appears multiple times, then it appears
672 * in the result table in the proper location for its first appearance.
674 * Constraints (including NOT NULL constraints) for the child table
675 * are the union of all relevant constraints, from both the child schema
678 * The default value for a child column is defined as:
679 * (1) If the child schema specifies a default, that value is used.
680 * (2) If neither the child nor any parent specifies a default, then
681 * the column will not have a default.
682 * (3) If conflicting defaults are inherited from different parents
683 * (and not overridden by the child), an error is raised.
684 * (4) Otherwise the inherited default is used.
685 * Rule (3) is new in Postgres 7.1; in earlier releases you got a
686 * rather arbitrary choice of which parent default to use.
690 MergeAttributes(List *schema, List *supers, bool istemp,
691 List **supOids, List **supconstr, int *supOidCount)
694 List *inhSchema = NIL;
695 List *parentOids = NIL;
696 List *constraints = NIL;
697 int parentsWithOids = 0;
698 bool have_bogus_defaults = false;
699 char *bogus_marker = "Bogus!"; /* marks conflicting
704 * Check for and reject tables with too many columns. We perform
705 * this check relatively early for two reasons: (a) we don't run
706 * the risk of overflowing an AttrNumber in subsequent code (b) an
707 * O(n^2) algorithm is okay if we're processing <= 1600 columns,
708 * but could take minutes to execute if the user attempts to
709 * create a table with hundreds of thousands of columns.
711 * Note that we also need to check that any we do not exceed this
712 * figure after including columns from inherited relations.
714 if (list_length(schema) > MaxHeapAttributeNumber)
716 (errcode(ERRCODE_TOO_MANY_COLUMNS),
717 errmsg("tables can have at most %d columns",
718 MaxHeapAttributeNumber)));
721 * Check for duplicate names in the explicit list of attributes.
723 * Although we might consider merging such entries in the same way that
724 * we handle name conflicts for inherited attributes, it seems to make
725 * more sense to assume such conflicts are errors.
727 foreach(entry, schema)
729 ColumnDef *coldef = lfirst(entry);
732 for_each_cell(rest, lnext(entry))
734 ColumnDef *restdef = lfirst(rest);
736 if (strcmp(coldef->colname, restdef->colname) == 0)
738 (errcode(ERRCODE_DUPLICATE_COLUMN),
739 errmsg("column \"%s\" duplicated",
745 * Scan the parents left-to-right, and merge their attributes to form
746 * a list of inherited attributes (inhSchema). Also check to see if
747 * we need to inherit an OID column.
750 foreach(entry, supers)
752 RangeVar *parent = (RangeVar *) lfirst(entry);
756 AttrNumber *newattno;
757 AttrNumber parent_attno;
759 relation = heap_openrv(parent, AccessShareLock);
761 if (relation->rd_rel->relkind != RELKIND_RELATION)
763 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
764 errmsg("inherited relation \"%s\" is not a table",
766 /* Permanent rels cannot inherit from temporary ones */
767 if (!istemp && isTempNamespace(RelationGetNamespace(relation)))
769 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
770 errmsg("cannot inherit from temporary relation \"%s\"",
774 * We should have an UNDER permission flag for this, but for now,
775 * demand that creator of a child table own the parent.
777 if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
778 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
779 RelationGetRelationName(relation));
782 * Reject duplications in the list of parents.
784 if (list_member_oid(parentOids, RelationGetRelid(relation)))
786 (errcode(ERRCODE_DUPLICATE_TABLE),
787 errmsg("inherited relation \"%s\" duplicated",
790 parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
792 if (relation->rd_rel->relhasoids)
795 tupleDesc = RelationGetDescr(relation);
796 constr = tupleDesc->constr;
799 * newattno[] will contain the child-table attribute numbers for
800 * the attributes of this parent table. (They are not the same
801 * for parents after the first one, nor if we have dropped
804 newattno = (AttrNumber *)
805 palloc(tupleDesc->natts * sizeof(AttrNumber));
807 for (parent_attno = 1; parent_attno <= tupleDesc->natts;
810 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
811 char *attributeName = NameStr(attribute->attname);
817 * Ignore dropped columns in the parent.
819 if (attribute->attisdropped)
822 * change_varattnos_of_a_node asserts that this is greater
823 * than zero, so if anything tries to use it, we should
826 newattno[parent_attno - 1] = 0;
831 * Does it conflict with some previously inherited column?
833 exist_attno = findAttrByName(attributeName, inhSchema);
837 * Yes, try to merge the two column definitions. They must
838 * have the same type and typmod.
841 (errmsg("merging multiple inherited definitions of column \"%s\"",
843 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
844 if (typenameTypeId(def->typename) != attribute->atttypid ||
845 def->typename->typmod != attribute->atttypmod)
847 (errcode(ERRCODE_DATATYPE_MISMATCH),
848 errmsg("inherited column \"%s\" has a type conflict",
850 errdetail("%s versus %s",
851 TypeNameToString(def->typename),
852 format_type_be(attribute->atttypid))));
854 /* Merge of NOT NULL constraints = OR 'em together */
855 def->is_not_null |= attribute->attnotnull;
856 /* Default and other constraints are handled below */
857 newattno[parent_attno - 1] = exist_attno;
862 * No, create a new inherited column
864 def = makeNode(ColumnDef);
865 def->colname = pstrdup(attributeName);
866 typename = makeNode(TypeName);
867 typename->typeid = attribute->atttypid;
868 typename->typmod = attribute->atttypmod;
869 def->typename = typename;
871 def->is_local = false;
872 def->is_not_null = attribute->attnotnull;
873 def->raw_default = NULL;
874 def->cooked_default = NULL;
875 def->constraints = NIL;
877 inhSchema = lappend(inhSchema, def);
878 newattno[parent_attno - 1] = ++child_attno;
882 * Copy default if any
884 if (attribute->atthasdef)
886 char *this_default = NULL;
887 AttrDefault *attrdef;
890 /* Find default in constraint structure */
891 Assert(constr != NULL);
892 attrdef = constr->defval;
893 for (i = 0; i < constr->num_defval; i++)
895 if (attrdef[i].adnum == parent_attno)
897 this_default = attrdef[i].adbin;
901 Assert(this_default != NULL);
904 * If default expr could contain any vars, we'd need to
905 * fix 'em, but it can't; so default is ready to apply to
908 * If we already had a default from some prior parent, check
909 * to see if they are the same. If so, no problem; if
910 * not, mark the column as having a bogus default. Below,
911 * we will complain if the bogus default isn't overridden
912 * by the child schema.
914 Assert(def->raw_default == NULL);
915 if (def->cooked_default == NULL)
916 def->cooked_default = pstrdup(this_default);
917 else if (strcmp(def->cooked_default, this_default) != 0)
919 def->cooked_default = bogus_marker;
920 have_bogus_defaults = true;
926 * Now copy the constraints of this parent, adjusting attnos using
927 * the completed newattno[] map
929 if (constr && constr->num_check > 0)
931 ConstrCheck *check = constr->check;
934 for (i = 0; i < constr->num_check; i++)
936 Constraint *cdef = makeNode(Constraint);
939 cdef->contype = CONSTR_CHECK;
940 cdef->name = pstrdup(check[i].ccname);
941 cdef->raw_expr = NULL;
942 /* adjust varattnos of ccbin here */
943 expr = stringToNode(check[i].ccbin);
944 change_varattnos_of_a_node(expr, newattno);
945 cdef->cooked_expr = nodeToString(expr);
946 constraints = lappend(constraints, cdef);
953 * Close the parent rel, but keep our AccessShareLock on it until
954 * xact commit. That will prevent someone else from deleting or
955 * ALTERing the parent before the child is committed.
957 heap_close(relation, NoLock);
961 * If we had no inherited attributes, the result schema is just the
962 * explicitly declared columns. Otherwise, we need to merge the
963 * declared columns into the inherited schema list.
965 if (inhSchema != NIL)
967 foreach(entry, schema)
969 ColumnDef *newdef = lfirst(entry);
970 char *attributeName = newdef->colname;
974 * Does it conflict with some previously inherited column?
976 exist_attno = findAttrByName(attributeName, inhSchema);
982 * Yes, try to merge the two column definitions. They must
983 * have the same type and typmod.
986 (errmsg("merging column \"%s\" with inherited definition",
988 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
989 if (typenameTypeId(def->typename) != typenameTypeId(newdef->typename) ||
990 def->typename->typmod != newdef->typename->typmod)
992 (errcode(ERRCODE_DATATYPE_MISMATCH),
993 errmsg("column \"%s\" has a type conflict",
995 errdetail("%s versus %s",
996 TypeNameToString(def->typename),
997 TypeNameToString(newdef->typename))));
998 /* Mark the column as locally defined */
999 def->is_local = true;
1000 /* Merge of NOT NULL constraints = OR 'em together */
1001 def->is_not_null |= newdef->is_not_null;
1002 /* If new def has a default, override previous default */
1003 if (newdef->raw_default != NULL)
1005 def->raw_default = newdef->raw_default;
1006 def->cooked_default = newdef->cooked_default;
1012 * No, attach new column to result schema
1014 inhSchema = lappend(inhSchema, newdef);
1021 * Check that we haven't exceeded the legal # of columns after
1022 * merging in inherited columns.
1024 if (list_length(schema) > MaxHeapAttributeNumber)
1026 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1027 errmsg("tables can have at most %d columns",
1028 MaxHeapAttributeNumber)));
1032 * If we found any conflicting parent default values, check to make
1033 * sure they were overridden by the child.
1035 if (have_bogus_defaults)
1037 foreach(entry, schema)
1039 ColumnDef *def = lfirst(entry);
1041 if (def->cooked_default == bogus_marker)
1043 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
1044 errmsg("column \"%s\" inherits conflicting default values",
1046 errhint("To resolve the conflict, specify a default explicitly.")));
1050 *supOids = parentOids;
1051 *supconstr = constraints;
1052 *supOidCount = parentsWithOids;
1057 * complementary static functions for MergeAttributes().
1059 * Varattnos of pg_constraint.conbin must be rewritten when subclasses inherit
1060 * constraints from parent classes, since the inherited attributes could
1061 * be given different column numbers in multiple-inheritance cases.
1063 * Note that the passed node tree is modified in place!
1066 change_varattnos_walker(Node *node, const AttrNumber *newattno)
1072 Var *var = (Var *) node;
1074 if (var->varlevelsup == 0 && var->varno == 1 &&
1078 * ??? the following may be a problem when the node is
1079 * multiply referenced though stringToNode() doesn't create
1080 * such a node currently.
1082 Assert(newattno[var->varattno - 1] > 0);
1083 var->varattno = newattno[var->varattno - 1];
1087 return expression_tree_walker(node, change_varattnos_walker,
1092 change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1094 return change_varattnos_walker(node, newattno);
1098 * StoreCatalogInheritance
1099 * Updates the system catalogs with proper inheritance information.
1101 * supers is a list of the OIDs of the new relation's direct ancestors.
1104 StoreCatalogInheritance(Oid relationId, List *supers)
1115 AssertArg(OidIsValid(relationId));
1121 * Store INHERITS information in pg_inherits using direct ancestors
1122 * only. Also enter dependencies on the direct ancestors, and make
1123 * sure they are marked with relhassubclass = true.
1125 * (Once upon a time, both direct and indirect ancestors were found here
1126 * and then entered into pg_ipl. Since that catalog doesn't exist
1127 * anymore, there's no need to look for indirect ancestors.)
1129 relation = heap_open(InheritsRelationId, RowExclusiveLock);
1130 desc = RelationGetDescr(relation);
1133 foreach(entry, supers)
1135 Oid parentOid = lfirst_oid(entry);
1136 Datum datum[Natts_pg_inherits];
1137 char nullarr[Natts_pg_inherits];
1138 ObjectAddress childobject,
1141 datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
1142 datum[1] = ObjectIdGetDatum(parentOid); /* inhparent */
1143 datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
1149 tuple = heap_formtuple(desc, datum, nullarr);
1151 simple_heap_insert(relation, tuple);
1153 CatalogUpdateIndexes(relation, tuple);
1155 heap_freetuple(tuple);
1158 * Store a dependency too
1160 parentobject.classId = RelationRelationId;
1161 parentobject.objectId = parentOid;
1162 parentobject.objectSubId = 0;
1163 childobject.classId = RelationRelationId;
1164 childobject.objectId = relationId;
1165 childobject.objectSubId = 0;
1167 recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
1170 * Mark the parent as having subclasses.
1172 setRelhassubclassInRelation(parentOid, true);
1177 heap_close(relation, RowExclusiveLock);
1181 * Look for an existing schema entry with the given name.
1183 * Returns the index (starting with 1) if attribute already exists in schema,
1187 findAttrByName(const char *attributeName, List *schema)
1194 ColumnDef *def = lfirst(s);
1196 if (strcmp(attributeName, def->colname) == 0)
1205 * Update a relation's pg_class.relhassubclass entry to the given value
1208 setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1210 Relation relationRelation;
1212 Form_pg_class classtuple;
1215 * Fetch a modifiable copy of the tuple, modify it, update pg_class.
1217 * If the tuple already has the right relhassubclass setting, we don't
1218 * need to update it, but we still need to issue an SI inval message.
1220 relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
1221 tuple = SearchSysCacheCopy(RELOID,
1222 ObjectIdGetDatum(relationId),
1224 if (!HeapTupleIsValid(tuple))
1225 elog(ERROR, "cache lookup failed for relation %u", relationId);
1226 classtuple = (Form_pg_class) GETSTRUCT(tuple);
1228 if (classtuple->relhassubclass != relhassubclass)
1230 classtuple->relhassubclass = relhassubclass;
1231 simple_heap_update(relationRelation, &tuple->t_self, tuple);
1233 /* keep the catalog indexes up to date */
1234 CatalogUpdateIndexes(relationRelation, tuple);
1238 /* no need to change tuple, but force relcache rebuild anyway */
1239 CacheInvalidateRelcacheByTuple(tuple);
1242 heap_freetuple(tuple);
1243 heap_close(relationRelation, RowExclusiveLock);
1248 * renameatt - changes the name of a attribute in a relation
1250 * Attname attribute is changed in attribute catalog.
1251 * No record of the previous attname is kept (correct?).
1253 * get proper relrelation from relation catalog (if not arg)
1254 * scan attribute catalog
1255 * for name conflict (within rel)
1256 * for original attribute (if not arg)
1257 * modify attname in attribute tuple
1258 * insert modified attribute in attribute catalog
1259 * delete original attribute from attribute catalog
1262 renameatt(Oid myrelid,
1263 const char *oldattname,
1264 const char *newattname,
1268 Relation targetrelation;
1269 Relation attrelation;
1271 Form_pg_attribute attform;
1274 ListCell *indexoidscan;
1277 * Grab an exclusive lock on the target table, which we will NOT
1278 * release until end of transaction.
1280 targetrelation = relation_open(myrelid, AccessExclusiveLock);
1283 * permissions checking. this would normally be done in utility.c,
1284 * but this particular routine is recursive.
1286 * normally, only the owner of a class can change its schema.
1288 if (!pg_class_ownercheck(myrelid, GetUserId()))
1289 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
1290 RelationGetRelationName(targetrelation));
1291 if (!allowSystemTableMods && IsSystemRelation(targetrelation))
1293 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1294 errmsg("permission denied: \"%s\" is a system catalog",
1295 RelationGetRelationName(targetrelation))));
1298 * if the 'recurse' flag is set then we are supposed to rename this
1299 * attribute in all classes that inherit from 'relname' (as well as in
1302 * any permissions or problems with duplicate attributes will cause the
1303 * whole transaction to abort, which is what we want -- all or
1311 /* this routine is actually in the planner */
1312 children = find_all_inheritors(myrelid);
1315 * find_all_inheritors does the recursive search of the
1316 * inheritance hierarchy, so all we have to do is process all of
1317 * the relids in the list that it returns.
1319 foreach(child, children)
1321 Oid childrelid = lfirst_oid(child);
1323 if (childrelid == myrelid)
1325 /* note we need not recurse again */
1326 renameatt(childrelid, oldattname, newattname, false, true);
1332 * If we are told not to recurse, there had better not be any
1333 * child tables; else the rename would put them out of step.
1336 find_inheritance_children(myrelid) != NIL)
1338 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1339 errmsg("inherited column \"%s\" must be renamed in child tables too",
1343 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
1345 atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
1346 if (!HeapTupleIsValid(atttup))
1348 (errcode(ERRCODE_UNDEFINED_COLUMN),
1349 errmsg("column \"%s\" does not exist",
1351 attform = (Form_pg_attribute) GETSTRUCT(atttup);
1353 attnum = attform->attnum;
1356 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1357 errmsg("cannot rename system column \"%s\"",
1361 * if the attribute is inherited, forbid the renaming, unless we are
1362 * already inside a recursive rename.
1364 if (attform->attinhcount > 0 && !recursing)
1366 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1367 errmsg("cannot rename inherited column \"%s\"",
1370 /* should not already exist */
1371 /* this test is deliberately not attisdropped-aware */
1372 if (SearchSysCacheExists(ATTNAME,
1373 ObjectIdGetDatum(myrelid),
1374 PointerGetDatum(newattname),
1377 (errcode(ERRCODE_DUPLICATE_COLUMN),
1378 errmsg("column \"%s\" of relation \"%s\" already exists",
1379 newattname, RelationGetRelationName(targetrelation))));
1381 namestrcpy(&(attform->attname), newattname);
1383 simple_heap_update(attrelation, &atttup->t_self, atttup);
1385 /* keep system catalog indexes current */
1386 CatalogUpdateIndexes(attrelation, atttup);
1388 heap_freetuple(atttup);
1391 * Update column names of indexes that refer to the column being
1394 indexoidlist = RelationGetIndexList(targetrelation);
1396 foreach(indexoidscan, indexoidlist)
1398 Oid indexoid = lfirst_oid(indexoidscan);
1400 Form_pg_index indexform;
1404 * Scan through index columns to see if there's any simple index
1405 * entries for this attribute. We ignore expressional entries.
1407 indextup = SearchSysCache(INDEXRELID,
1408 ObjectIdGetDatum(indexoid),
1410 if (!HeapTupleIsValid(indextup))
1411 elog(ERROR, "cache lookup failed for index %u", indexoid);
1412 indexform = (Form_pg_index) GETSTRUCT(indextup);
1414 for (i = 0; i < indexform->indnatts; i++)
1416 if (attnum != indexform->indkey.values[i])
1420 * Found one, rename it.
1422 atttup = SearchSysCacheCopy(ATTNUM,
1423 ObjectIdGetDatum(indexoid),
1424 Int16GetDatum(i + 1),
1426 if (!HeapTupleIsValid(atttup))
1427 continue; /* should we raise an error? */
1430 * Update the (copied) attribute tuple.
1432 namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
1435 simple_heap_update(attrelation, &atttup->t_self, atttup);
1437 /* keep system catalog indexes current */
1438 CatalogUpdateIndexes(attrelation, atttup);
1440 heap_freetuple(atttup);
1443 ReleaseSysCache(indextup);
1446 list_free(indexoidlist);
1448 heap_close(attrelation, RowExclusiveLock);
1451 * Update att name in any RI triggers associated with the relation.
1453 if (targetrelation->rd_rel->reltriggers > 0)
1455 /* update tgargs column reference where att is primary key */
1456 update_ri_trigger_args(RelationGetRelid(targetrelation),
1457 oldattname, newattname,
1459 /* update tgargs column reference where att is foreign key */
1460 update_ri_trigger_args(RelationGetRelid(targetrelation),
1461 oldattname, newattname,
1465 relation_close(targetrelation, NoLock); /* close rel but keep lock */
1469 * renamerel - change the name of a relation
1471 * XXX - When renaming sequences, we don't bother to modify the
1472 * sequence name that is stored within the sequence itself
1473 * (this would cause problems with MVCC). In the future,
1474 * the sequence name should probably be removed from the
1475 * sequence, AFAIK there's no need for it to be there.
1478 renamerel(Oid myrelid, const char *newrelname)
1480 Relation targetrelation;
1481 Relation relrelation; /* for RELATION relation */
1486 bool relhastriggers;
1489 * Grab an exclusive lock on the target table or index, which we will
1490 * NOT release until end of transaction.
1492 targetrelation = relation_open(myrelid, AccessExclusiveLock);
1494 oldrelname = pstrdup(RelationGetRelationName(targetrelation));
1495 namespaceId = RelationGetNamespace(targetrelation);
1497 if (!allowSystemTableMods && IsSystemRelation(targetrelation))
1499 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1500 errmsg("permission denied: \"%s\" is a system catalog",
1501 RelationGetRelationName(targetrelation))));
1503 relkind = targetrelation->rd_rel->relkind;
1504 relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
1507 * Find relation's pg_class tuple, and make sure newrelname isn't in
1510 relrelation = heap_open(RelationRelationId, RowExclusiveLock);
1512 reltup = SearchSysCacheCopy(RELOID,
1513 PointerGetDatum(myrelid),
1515 if (!HeapTupleIsValid(reltup)) /* shouldn't happen */
1516 elog(ERROR, "cache lookup failed for relation %u", myrelid);
1518 if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
1520 (errcode(ERRCODE_DUPLICATE_TABLE),
1521 errmsg("relation \"%s\" already exists",
1525 * Update pg_class tuple with new relname. (Scribbling on reltup is
1526 * OK because it's a copy...)
1528 namestrcpy(&(((Form_pg_class) GETSTRUCT(reltup))->relname), newrelname);
1530 simple_heap_update(relrelation, &reltup->t_self, reltup);
1532 /* keep the system catalog indexes current */
1533 CatalogUpdateIndexes(relrelation, reltup);
1535 heap_freetuple(reltup);
1536 heap_close(relrelation, RowExclusiveLock);
1539 * Also rename the associated type, if any.
1541 if (relkind != RELKIND_INDEX)
1542 TypeRename(oldrelname, namespaceId, newrelname);
1545 * Update rel name in any RI triggers associated with the relation.
1549 /* update tgargs where relname is primary key */
1550 update_ri_trigger_args(myrelid,
1554 /* update tgargs where relname is foreign key */
1555 update_ri_trigger_args(myrelid,
1562 * Close rel, but keep exclusive lock!
1564 relation_close(targetrelation, NoLock);
1568 * Scan pg_trigger for RI triggers that are on the specified relation
1569 * (if fk_scan is false) or have it as the tgconstrrel (if fk_scan
1570 * is true). Update RI trigger args fields matching oldname to contain
1571 * newname instead. If update_relname is true, examine the relname
1572 * fields; otherwise examine the attname fields.
1575 update_ri_trigger_args(Oid relid,
1576 const char *oldname,
1577 const char *newname,
1579 bool update_relname)
1582 ScanKeyData skey[1];
1583 SysScanDesc trigscan;
1585 Datum values[Natts_pg_trigger];
1586 char nulls[Natts_pg_trigger];
1587 char replaces[Natts_pg_trigger];
1589 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
1592 ScanKeyInit(&skey[0],
1593 Anum_pg_trigger_tgconstrrelid,
1594 BTEqualStrategyNumber, F_OIDEQ,
1595 ObjectIdGetDatum(relid));
1596 trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndexId,
1602 ScanKeyInit(&skey[0],
1603 Anum_pg_trigger_tgrelid,
1604 BTEqualStrategyNumber, F_OIDEQ,
1605 ObjectIdGetDatum(relid));
1606 trigscan = systable_beginscan(tgrel, TriggerRelidNameIndexId,
1611 while ((tuple = systable_getnext(trigscan)) != NULL)
1613 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
1623 const char *arga[RI_MAX_ARGUMENTS];
1626 tg_type = RI_FKey_trigger_type(pg_trigger->tgfoid);
1627 if (tg_type == RI_TRIGGER_NONE)
1629 /* Not an RI trigger, forget it */
1634 * It is an RI trigger, so parse the tgargs bytea.
1636 * NB: we assume the field will never be compressed or moved out of
1637 * line; so does trigger.c ...
1639 tgnargs = pg_trigger->tgnargs;
1641 DatumGetPointer(fastgetattr(tuple,
1642 Anum_pg_trigger_tgargs,
1643 tgrel->rd_att, &isnull));
1644 if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
1645 tgnargs > RI_MAX_ARGUMENTS)
1647 /* This probably shouldn't happen, but ignore busted triggers */
1650 argp = (const char *) VARDATA(val);
1651 for (i = 0; i < tgnargs; i++)
1654 argp += strlen(argp) + 1;
1658 * Figure out which item(s) to look at. If the trigger is
1659 * primary-key type and attached to my rel, I should look at the
1660 * PK fields; if it is foreign-key type and attached to my rel, I
1661 * should look at the FK fields. But the opposite rule holds when
1662 * examining triggers found by tgconstrrel search.
1664 examine_pk = (tg_type == RI_TRIGGER_PK) == (!fk_scan);
1669 /* Change the relname if needed */
1670 i = examine_pk ? RI_PK_RELNAME_ARGNO : RI_FK_RELNAME_ARGNO;
1671 if (strcmp(arga[i], oldname) == 0)
1679 /* Change attname(s) if needed */
1680 i = examine_pk ? RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_PK_IDX :
1681 RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_FK_IDX;
1682 for (; i < tgnargs; i += 2)
1684 if (strcmp(arga[i], oldname) == 0)
1694 /* Don't need to update this tuple */
1699 * Construct modified tgargs bytea.
1702 for (i = 0; i < tgnargs; i++)
1703 newlen += strlen(arga[i]) + 1;
1704 newtgargs = (bytea *) palloc(newlen);
1705 VARATT_SIZEP(newtgargs) = newlen;
1707 for (i = 0; i < tgnargs; i++)
1709 strcpy(((char *) newtgargs) + newlen, arga[i]);
1710 newlen += strlen(arga[i]) + 1;
1714 * Build modified tuple.
1716 for (i = 0; i < Natts_pg_trigger; i++)
1718 values[i] = (Datum) 0;
1722 values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(newtgargs);
1723 replaces[Anum_pg_trigger_tgargs - 1] = 'r';
1725 tuple = heap_modifytuple(tuple, RelationGetDescr(tgrel), values, nulls, replaces);
1728 * Update pg_trigger and its indexes
1730 simple_heap_update(tgrel, &tuple->t_self, tuple);
1732 CatalogUpdateIndexes(tgrel, tuple);
1735 * Invalidate trigger's relation's relcache entry so that other
1736 * backends (and this one too!) are sent SI message to make them
1737 * rebuild relcache entries. (Ideally this should happen
1740 * We can skip this for triggers on relid itself, since that relcache
1741 * flush will happen anyway due to the table or column rename. We
1742 * just need to catch the far ends of RI relationships.
1744 pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
1745 if (pg_trigger->tgrelid != relid)
1746 CacheInvalidateRelcacheByRelid(pg_trigger->tgrelid);
1748 /* free up our scratch memory */
1750 heap_freetuple(tuple);
1753 systable_endscan(trigscan);
1755 heap_close(tgrel, RowExclusiveLock);
1758 * Increment cmd counter to make updates visible; this is needed in
1759 * case the same tuple has to be updated again by next pass (can
1760 * happen in case of a self-referential FK relationship).
1762 CommandCounterIncrement();
1767 * Execute ALTER TABLE, which can be a list of subcommands
1769 * ALTER TABLE is performed in three phases:
1770 * 1. Examine subcommands and perform pre-transformation checking.
1771 * 2. Update system catalogs.
1772 * 3. Scan table(s) to check new constraints, and optionally recopy
1773 * the data into new table(s).
1774 * Phase 3 is not performed unless one or more of the subcommands requires
1775 * it. The intention of this design is to allow multiple independent
1776 * updates of the table schema to be performed with only one pass over the
1779 * ATPrepCmd performs phase 1. A "work queue" entry is created for
1780 * each table to be affected (there may be multiple affected tables if the
1781 * commands traverse a table inheritance hierarchy). Also we do preliminary
1782 * validation of the subcommands, including parse transformation of those
1783 * expressions that need to be evaluated with respect to the old table
1786 * ATRewriteCatalogs performs phase 2 for each affected table (note that
1787 * phases 2 and 3 do no explicit recursion, since phase 1 already did it).
1788 * Certain subcommands need to be performed before others to avoid
1789 * unnecessary conflicts; for example, DROP COLUMN should come before
1790 * ADD COLUMN. Therefore phase 1 divides the subcommands into multiple
1791 * lists, one for each logical "pass" of phase 2.
1793 * ATRewriteTables performs phase 3 for those tables that need it.
1795 * Thanks to the magic of MVCC, an error anywhere along the way rolls back
1796 * the whole operation; we don't have to do anything special to clean up.
1799 AlterTable(AlterTableStmt *stmt)
1801 ATController(relation_openrv(stmt->relation, AccessExclusiveLock),
1803 interpretInhOption(stmt->relation->inhOpt));
1807 * AlterTableInternal
1809 * ALTER TABLE with target specified by OID
1812 AlterTableInternal(Oid relid, List *cmds, bool recurse)
1814 ATController(relation_open(relid, AccessExclusiveLock),
1820 ATController(Relation rel, List *cmds, bool recurse)
1825 /* Phase 1: preliminary examination of commands, create work queue */
1828 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
1830 ATPrepCmd(&wqueue, rel, cmd, recurse, false);
1833 /* Close the relation, but keep lock until commit */
1834 relation_close(rel, NoLock);
1836 /* Phase 2: update system catalogs */
1837 ATRewriteCatalogs(&wqueue);
1839 /* Phase 3: scan/rewrite tables as needed */
1840 ATRewriteTables(&wqueue);
1846 * Traffic cop for ALTER TABLE Phase 1 operations, including simple
1847 * recursion and permission checks.
1849 * Caller must have acquired AccessExclusiveLock on relation already.
1850 * This lock should be held until commit.
1853 ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
1854 bool recurse, bool recursing)
1856 AlteredTableInfo *tab;
1859 /* Find or create work queue entry for this table */
1860 tab = ATGetQueueEntry(wqueue, rel);
1863 * Copy the original subcommand for each table. This avoids conflicts
1864 * when different child tables need to make different parse
1865 * transformations (for example, the same column may have different
1866 * column numbers in different children).
1868 cmd = copyObject(cmd);
1871 * Do permissions checking, recursion to child tables if needed, and
1872 * any additional phase-1 processing needed.
1874 switch (cmd->subtype)
1876 case AT_AddColumn: /* ADD COLUMN */
1877 ATSimplePermissions(rel, false);
1878 /* Performs own recursion */
1879 ATPrepAddColumn(wqueue, rel, recurse, cmd);
1880 pass = AT_PASS_ADD_COL;
1882 case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
1885 * We allow defaults on views so that INSERT into a view can
1886 * have default-ish behavior. This works because the rewriter
1887 * substitutes default values into INSERTs before it expands
1890 ATSimplePermissions(rel, true);
1891 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1892 /* No command-specific prep needed */
1893 pass = AT_PASS_ADD_CONSTR;
1895 case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
1896 ATSimplePermissions(rel, false);
1897 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1898 /* No command-specific prep needed */
1899 pass = AT_PASS_DROP;
1901 case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
1902 ATSimplePermissions(rel, false);
1903 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1904 /* No command-specific prep needed */
1905 pass = AT_PASS_ADD_CONSTR;
1907 case AT_SetStatistics: /* ALTER COLUMN STATISTICS */
1908 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1909 /* Performs own permission checks */
1910 ATPrepSetStatistics(rel, cmd->name, cmd->def);
1911 pass = AT_PASS_COL_ATTRS;
1913 case AT_SetStorage: /* ALTER COLUMN STORAGE */
1914 ATSimplePermissions(rel, false);
1915 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1916 /* No command-specific prep needed */
1917 pass = AT_PASS_COL_ATTRS;
1919 case AT_DropColumn: /* DROP COLUMN */
1920 ATSimplePermissions(rel, false);
1921 /* Recursion occurs during execution phase */
1922 /* No command-specific prep needed except saving recurse flag */
1924 cmd->subtype = AT_DropColumnRecurse;
1925 pass = AT_PASS_DROP;
1927 case AT_AddIndex: /* ADD INDEX */
1928 ATSimplePermissions(rel, false);
1929 /* This command never recurses */
1930 /* No command-specific prep needed */
1931 pass = AT_PASS_ADD_INDEX;
1933 case AT_AddConstraint: /* ADD CONSTRAINT */
1934 ATSimplePermissions(rel, false);
1937 * Currently we recurse only for CHECK constraints, never for
1938 * foreign-key constraints. UNIQUE/PKEY constraints won't be
1941 if (IsA(cmd->def, Constraint))
1942 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1943 /* No command-specific prep needed */
1944 pass = AT_PASS_ADD_CONSTR;
1946 case AT_DropConstraint: /* DROP CONSTRAINT */
1947 ATSimplePermissions(rel, false);
1948 /* Performs own recursion */
1949 ATPrepDropConstraint(wqueue, rel, recurse, cmd);
1950 pass = AT_PASS_DROP;
1952 case AT_DropConstraintQuietly: /* DROP CONSTRAINT for child */
1953 ATSimplePermissions(rel, false);
1954 ATSimpleRecursion(wqueue, rel, cmd, recurse);
1955 /* No command-specific prep needed */
1956 pass = AT_PASS_DROP;
1958 case AT_AlterColumnType: /* ALTER COLUMN TYPE */
1959 ATSimplePermissions(rel, false);
1960 /* Performs own recursion */
1961 ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd);
1962 pass = AT_PASS_ALTER_TYPE;
1964 case AT_ToastTable: /* CREATE TOAST TABLE */
1965 ATSimplePermissions(rel, false);
1966 /* This command never recurses */
1967 /* No command-specific prep needed */
1968 pass = AT_PASS_MISC;
1970 case AT_ChangeOwner: /* ALTER OWNER */
1971 /* This command never recurses */
1972 /* No command-specific prep needed */
1973 pass = AT_PASS_MISC;
1975 case AT_ClusterOn: /* CLUSTER ON */
1976 case AT_DropCluster: /* SET WITHOUT CLUSTER */
1977 ATSimplePermissions(rel, false);
1978 /* These commands never recurse */
1979 /* No command-specific prep needed */
1980 pass = AT_PASS_MISC;
1982 case AT_DropOids: /* SET WITHOUT OIDS */
1983 ATSimplePermissions(rel, false);
1984 /* Performs own recursion */
1985 if (rel->rd_rel->relhasoids)
1987 AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
1989 dropCmd->subtype = AT_DropColumn;
1990 dropCmd->name = pstrdup("oid");
1991 dropCmd->behavior = cmd->behavior;
1992 ATPrepCmd(wqueue, rel, dropCmd, recurse, false);
1994 pass = AT_PASS_DROP;
1996 case AT_SetTableSpace: /* SET TABLESPACE */
1997 /* This command never recurses */
1998 ATPrepSetTableSpace(tab, rel, cmd->name);
1999 pass = AT_PASS_MISC; /* doesn't actually matter */
2002 elog(ERROR, "unrecognized alter table type: %d",
2003 (int) cmd->subtype);
2004 pass = 0; /* keep compiler quiet */
2008 /* Add the subcommand to the appropriate list for phase 2 */
2009 tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
2015 * Traffic cop for ALTER TABLE Phase 2 operations. Subcommands are
2016 * dispatched in a "safe" execution order (designed to avoid unnecessary
2020 ATRewriteCatalogs(List **wqueue)
2026 * We process all the tables "in parallel", one pass at a time. This
2027 * is needed because we may have to propagate work from one table to
2028 * another (specifically, ALTER TYPE on a foreign key's PK has to
2029 * dispatch the re-adding of the foreign key constraint to the other
2030 * table). Work can only be propagated into later passes, however.
2032 for (pass = 0; pass < AT_NUM_PASSES; pass++)
2034 /* Go through each table that needs to be processed */
2035 foreach(ltab, *wqueue)
2037 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2038 List *subcmds = tab->subcmds[pass];
2046 * Exclusive lock was obtained by phase 1, needn't get it
2049 rel = relation_open(tab->relid, NoLock);
2051 foreach(lcmd, subcmds)
2052 ATExecCmd(tab, rel, (AlterTableCmd *) lfirst(lcmd));
2055 * After the ALTER TYPE pass, do cleanup work (this is not
2056 * done in ATExecAlterColumnType since it should be done only
2057 * once if multiple columns of a table are altered).
2059 if (pass == AT_PASS_ALTER_TYPE)
2060 ATPostAlterTypeCleanup(wqueue, tab);
2062 relation_close(rel, NoLock);
2067 * Do an implicit CREATE TOAST TABLE if we executed any subcommands
2068 * that might have added a column or changed column storage.
2070 foreach(ltab, *wqueue)
2072 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2074 if (tab->relkind == RELKIND_RELATION &&
2075 (tab->subcmds[AT_PASS_ADD_COL] ||
2076 tab->subcmds[AT_PASS_ALTER_TYPE] ||
2077 tab->subcmds[AT_PASS_COL_ATTRS]))
2078 AlterTableCreateToastTable(tab->relid, true);
2083 * ATExecCmd: dispatch a subcommand to appropriate execution routine
2086 ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
2088 switch (cmd->subtype)
2090 case AT_AddColumn: /* ADD COLUMN */
2091 ATExecAddColumn(tab, rel, (ColumnDef *) cmd->def);
2093 case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
2094 ATExecColumnDefault(rel, cmd->name, cmd->def);
2096 case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
2097 ATExecDropNotNull(rel, cmd->name);
2099 case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
2100 ATExecSetNotNull(tab, rel, cmd->name);
2102 case AT_SetStatistics: /* ALTER COLUMN STATISTICS */
2103 ATExecSetStatistics(rel, cmd->name, cmd->def);
2105 case AT_SetStorage: /* ALTER COLUMN STORAGE */
2106 ATExecSetStorage(rel, cmd->name, cmd->def);
2108 case AT_DropColumn: /* DROP COLUMN */
2109 ATExecDropColumn(rel, cmd->name, cmd->behavior, false, false);
2111 case AT_DropColumnRecurse: /* DROP COLUMN with recursion */
2112 ATExecDropColumn(rel, cmd->name, cmd->behavior, true, false);
2114 case AT_AddIndex: /* ADD INDEX */
2115 ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false);
2117 case AT_ReAddIndex: /* ADD INDEX */
2118 ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true);
2120 case AT_AddConstraint: /* ADD CONSTRAINT */
2121 ATExecAddConstraint(tab, rel, cmd->def);
2123 case AT_DropConstraint: /* DROP CONSTRAINT */
2124 ATExecDropConstraint(rel, cmd->name, cmd->behavior, false);
2126 case AT_DropConstraintQuietly: /* DROP CONSTRAINT for child */
2127 ATExecDropConstraint(rel, cmd->name, cmd->behavior, true);
2129 case AT_AlterColumnType: /* ALTER COLUMN TYPE */
2130 ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def);
2132 case AT_ToastTable: /* CREATE TOAST TABLE */
2133 AlterTableCreateToastTable(RelationGetRelid(rel), false);
2135 case AT_ChangeOwner: /* ALTER OWNER */
2136 /* get_usesysid raises an error if no such user */
2137 ATExecChangeOwner(RelationGetRelid(rel), get_usesysid(cmd->name));
2139 case AT_ClusterOn: /* CLUSTER ON */
2140 ATExecClusterOn(rel, cmd->name);
2142 case AT_DropCluster: /* SET WITHOUT CLUSTER */
2143 ATExecDropCluster(rel);
2145 case AT_DropOids: /* SET WITHOUT OIDS */
2148 * Nothing to do here; we'll have generated a DropColumn
2149 * subcommand to do the real work
2152 case AT_SetTableSpace: /* SET TABLESPACE */
2155 * Nothing to do here; Phase 3 does the work
2159 elog(ERROR, "unrecognized alter table type: %d",
2160 (int) cmd->subtype);
2165 * Bump the command counter to ensure the next subcommand in the
2166 * sequence can see the changes so far
2168 CommandCounterIncrement();
2172 * ATRewriteTables: ALTER TABLE phase 3
2175 ATRewriteTables(List **wqueue)
2179 /* Go through each table that needs to be checked or rewritten */
2180 foreach(ltab, *wqueue)
2182 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2185 * We only need to rewrite the table if at least one column needs
2188 if (tab->newvals != NIL)
2190 /* Build a temporary relation and copy data */
2192 char NewHeapName[NAMEDATALEN];
2195 ObjectAddress object;
2197 OldHeap = heap_open(tab->relid, NoLock);
2200 * We can never allow rewriting of shared or nailed-in-cache
2201 * relations, because we can't support changing their
2202 * relfilenode values.
2204 if (OldHeap->rd_rel->relisshared || OldHeap->rd_isnailed)
2206 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2207 errmsg("cannot rewrite system relation \"%s\"",
2208 RelationGetRelationName(OldHeap))));
2211 * Don't allow rewrite on temp tables of other backends ...
2212 * their local buffer manager is not going to cope.
2214 if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
2216 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2217 errmsg("cannot rewrite temporary tables of other sessions")));
2220 * Select destination tablespace (same as original unless user
2221 * requested a change)
2223 if (tab->newTableSpace)
2224 NewTableSpace = tab->newTableSpace;
2226 NewTableSpace = OldHeap->rd_rel->reltablespace;
2228 heap_close(OldHeap, NoLock);
2231 * Create the new heap, using a temporary name in the same
2232 * namespace as the existing table. NOTE: there is some risk
2233 * of collision with user relnames. Working around this seems
2234 * more trouble than it's worth; in particular, we can't
2235 * create the new heap in a different namespace from the old,
2236 * or we will have problems with the TEMP status of temp
2239 snprintf(NewHeapName, sizeof(NewHeapName),
2240 "pg_temp_%u", tab->relid);
2242 OIDNewHeap = make_new_heap(tab->relid, NewHeapName, NewTableSpace);
2245 * Copy the heap data into the new table with the desired
2246 * modifications, and test the current data within the table
2247 * against new constraints generated by ALTER TABLE commands.
2249 ATRewriteTable(tab, OIDNewHeap);
2251 /* Swap the physical files of the old and new heaps. */
2252 swap_relation_files(tab->relid, OIDNewHeap);
2254 CommandCounterIncrement();
2256 /* Destroy new heap with old filenode */
2257 object.classId = RelationRelationId;
2258 object.objectId = OIDNewHeap;
2259 object.objectSubId = 0;
2262 * The new relation is local to our transaction and we know
2263 * nothing depends on it, so DROP_RESTRICT should be OK.
2265 performDeletion(&object, DROP_RESTRICT);
2266 /* performDeletion does CommandCounterIncrement at end */
2269 * Rebuild each index on the relation (but not the toast
2270 * table, which is all-new anyway). We do not need
2271 * CommandCounterIncrement() because reindex_relation does it.
2273 reindex_relation(tab->relid, false);
2278 * Test the current data within the table against new
2279 * constraints generated by ALTER TABLE commands, but don't
2282 if (tab->constraints != NIL)
2283 ATRewriteTable(tab, InvalidOid);
2286 * If we had SET TABLESPACE but no reason to reconstruct
2287 * tuples, just do a block-by-block copy.
2289 if (tab->newTableSpace)
2290 ATExecSetTableSpace(tab->relid, tab->newTableSpace);
2295 * Foreign key constraints are checked in a final pass, since (a) it's
2296 * generally best to examine each one separately, and (b) it's at
2297 * least theoretically possible that we have changed both relations of
2298 * the foreign key, and we'd better have finished both rewrites before
2299 * we try to read the tables.
2301 foreach(ltab, *wqueue)
2303 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2304 Relation rel = NULL;
2307 foreach(lcon, tab->constraints)
2309 NewConstraint *con = lfirst(lcon);
2311 if (con->contype == CONSTR_FOREIGN)
2313 FkConstraint *fkconstraint = (FkConstraint *) con->qual;
2318 /* Long since locked, no need for another */
2319 rel = heap_open(tab->relid, NoLock);
2322 refrel = heap_open(con->refrelid, RowShareLock);
2324 validateForeignKeyConstraint(fkconstraint, rel, refrel);
2326 heap_close(refrel, NoLock);
2331 heap_close(rel, NoLock);
2336 * ATRewriteTable: scan or rewrite one table
2338 * OIDNewHeap is InvalidOid if we don't need to rewrite
2341 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
2345 TupleDesc oldTupDesc;
2346 TupleDesc newTupDesc;
2347 bool needscan = false;
2353 * Open the relation(s). We have surely already locked the existing
2356 oldrel = heap_open(tab->relid, NoLock);
2357 oldTupDesc = tab->oldDesc;
2358 newTupDesc = RelationGetDescr(oldrel); /* includes all mods */
2360 if (OidIsValid(OIDNewHeap))
2361 newrel = heap_open(OIDNewHeap, AccessExclusiveLock);
2366 * If we need to rewrite the table, the operation has to be propagated
2367 * to tables that use this table's rowtype as a column type.
2369 * (Eventually this will probably become true for scans as well, but at
2370 * the moment a composite type does not enforce any constraints, so
2371 * it's not necessary/appropriate to enforce them just during ALTER.)
2374 find_composite_type_dependencies(oldrel->rd_rel->reltype,
2375 RelationGetRelationName(oldrel));
2378 * Generate the constraint and default execution states
2381 estate = CreateExecutorState();
2383 /* Build the needed expression execution states */
2384 foreach(l, tab->constraints)
2386 NewConstraint *con = lfirst(l);
2388 switch (con->contype)
2392 con->qualstate = (List *)
2393 ExecPrepareExpr((Expr *) con->qual, estate);
2395 case CONSTR_FOREIGN:
2396 /* Nothing to do here */
2398 case CONSTR_NOTNULL:
2402 elog(ERROR, "unrecognized constraint type: %d",
2403 (int) con->contype);
2407 foreach(l, tab->newvals)
2409 NewColumnValue *ex = lfirst(l);
2413 ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
2418 ExprContext *econtext;
2421 TupleTableSlot *oldslot;
2422 TupleTableSlot *newslot;
2425 MemoryContext oldCxt;
2426 List *dropped_attrs = NIL;
2429 econtext = GetPerTupleExprContext(estate);
2432 * Make tuple slots for old and new tuples. Note that even when
2433 * the tuples are the same, the tupDescs might not be (consider
2434 * ADD COLUMN without a default).
2436 oldslot = MakeSingleTupleTableSlot(oldTupDesc);
2437 newslot = MakeSingleTupleTableSlot(newTupDesc);
2439 /* Preallocate values/isnull arrays */
2440 i = Max(newTupDesc->natts, oldTupDesc->natts);
2441 values = (Datum *) palloc(i * sizeof(Datum));
2442 isnull = (bool *) palloc(i * sizeof(bool));
2443 memset(values, 0, i * sizeof(Datum));
2444 memset(isnull, true, i * sizeof(bool));
2447 * Any attributes that are dropped according to the new tuple
2448 * descriptor can be set to NULL. We precompute the list of
2449 * dropped attributes to avoid needing to do so in the
2452 for (i = 0; i < newTupDesc->natts; i++)
2454 if (newTupDesc->attrs[i]->attisdropped)
2455 dropped_attrs = lappend_int(dropped_attrs, i);
2459 * Scan through the rows, generating a new row if needed and then
2460 * checking all the constraints.
2462 scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
2465 * Switch to per-tuple memory context and reset it for each
2466 * tuple produced, so we don't leak memory.
2468 oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
2470 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
2474 /* Extract data from old tuple */
2475 heap_deform_tuple(tuple, oldTupDesc, values, isnull);
2477 /* Set dropped attributes to null in new tuple */
2478 foreach (lc, dropped_attrs)
2479 isnull[lfirst_int(lc)] = true;
2482 * Process supplied expressions to replace selected
2483 * columns. Expression inputs come from the old tuple.
2485 ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
2486 econtext->ecxt_scantuple = oldslot;
2488 foreach(l, tab->newvals)
2490 NewColumnValue *ex = lfirst(l);
2492 values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
2494 &isnull[ex->attnum - 1],
2499 * Form the new tuple. Note that we don't explicitly
2500 * pfree it, since the per-tuple memory context will
2503 tuple = heap_form_tuple(newTupDesc, values, isnull);
2506 /* Now check any constraints on the possibly-changed tuple */
2507 ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
2508 econtext->ecxt_scantuple = newslot;
2510 foreach(l, tab->constraints)
2512 NewConstraint *con = lfirst(l);
2514 switch (con->contype)
2517 if (!ExecQual(con->qualstate, econtext, true))
2519 (errcode(ERRCODE_CHECK_VIOLATION),
2520 errmsg("check constraint \"%s\" is violated by some row",
2523 case CONSTR_NOTNULL:
2528 d = heap_getattr(tuple, con->attnum, newTupDesc,
2532 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2533 errmsg("column \"%s\" contains null values",
2534 get_attname(tab->relid,
2538 case CONSTR_FOREIGN:
2539 /* Nothing to do here */
2542 elog(ERROR, "unrecognized constraint type: %d",
2543 (int) con->contype);
2547 /* Write the tuple out to the new relation */
2549 simple_heap_insert(newrel, tuple);
2551 ResetExprContext(econtext);
2553 CHECK_FOR_INTERRUPTS();
2556 MemoryContextSwitchTo(oldCxt);
2560 FreeExecutorState(estate);
2562 heap_close(oldrel, NoLock);
2564 heap_close(newrel, NoLock);
2568 * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
2570 static AlteredTableInfo *
2571 ATGetQueueEntry(List **wqueue, Relation rel)
2573 Oid relid = RelationGetRelid(rel);
2574 AlteredTableInfo *tab;
2577 foreach(ltab, *wqueue)
2579 tab = (AlteredTableInfo *) lfirst(ltab);
2580 if (tab->relid == relid)
2585 * Not there, so add it. Note that we make a copy of the relation's
2586 * existing descriptor before anything interesting can happen to it.
2588 tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
2590 tab->relkind = rel->rd_rel->relkind;
2591 tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));
2593 *wqueue = lappend(*wqueue, tab);
2599 * ATSimplePermissions
2601 * - Ensure that it is a relation (or possibly a view)
2602 * - Ensure this user is the owner
2603 * - Ensure that it is not a system table
2606 ATSimplePermissions(Relation rel, bool allowView)
2608 if (rel->rd_rel->relkind != RELKIND_RELATION)
2612 if (rel->rd_rel->relkind != RELKIND_VIEW)
2614 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2615 errmsg("\"%s\" is not a table or view",
2616 RelationGetRelationName(rel))));
2620 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2621 errmsg("\"%s\" is not a table",
2622 RelationGetRelationName(rel))));
2625 /* Permissions checks */
2626 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
2627 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
2628 RelationGetRelationName(rel));
2630 if (!allowSystemTableMods && IsSystemRelation(rel))
2632 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2633 errmsg("permission denied: \"%s\" is a system catalog",
2634 RelationGetRelationName(rel))));
2640 * Simple table recursion sufficient for most ALTER TABLE operations.
2641 * All direct and indirect children are processed in an unspecified order.
2642 * Note that if a child inherits from the original table via multiple
2643 * inheritance paths, it will be visited just once.
2646 ATSimpleRecursion(List **wqueue, Relation rel,
2647 AlterTableCmd *cmd, bool recurse)
2650 * Propagate to children if desired. Non-table relations never have
2651 * children, so no need to search in that case.
2653 if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
2655 Oid relid = RelationGetRelid(rel);
2659 /* this routine is actually in the planner */
2660 children = find_all_inheritors(relid);
2663 * find_all_inheritors does the recursive search of the
2664 * inheritance hierarchy, so all we have to do is process all of
2665 * the relids in the list that it returns.
2667 foreach(child, children)
2669 Oid childrelid = lfirst_oid(child);
2672 if (childrelid == relid)
2674 childrel = relation_open(childrelid, AccessExclusiveLock);
2675 ATPrepCmd(wqueue, childrel, cmd, false, true);
2676 relation_close(childrel, NoLock);
2682 * ATOneLevelRecursion
2684 * Here, we visit only direct inheritance children. It is expected that
2685 * the command's prep routine will recurse again to find indirect children.
2686 * When using this technique, a multiply-inheriting child will be visited
2690 ATOneLevelRecursion(List **wqueue, Relation rel,
2693 Oid relid = RelationGetRelid(rel);
2697 /* this routine is actually in the planner */
2698 children = find_inheritance_children(relid);
2700 foreach(child, children)
2702 Oid childrelid = lfirst_oid(child);
2705 childrel = relation_open(childrelid, AccessExclusiveLock);
2706 ATPrepCmd(wqueue, childrel, cmd, true, true);
2707 relation_close(childrel, NoLock);
2713 * find_composite_type_dependencies
2715 * Check to see if a table's rowtype is being used as a column in some
2716 * other table (possibly nested several levels deep in composite types!).
2717 * Eventually, we'd like to propagate the check or rewrite operation
2718 * into other such tables, but for now, just error out if we find any.
2720 * We assume that functions and views depending on the type are not reasons
2721 * to reject the ALTER. (How safe is this really?)
2724 find_composite_type_dependencies(Oid typeOid, const char *origTblName)
2728 SysScanDesc depScan;
2732 * We scan pg_depend to find those things that depend on the rowtype.
2733 * (We assume we can ignore refobjsubid for a rowtype.)
2735 depRel = heap_open(DependRelationId, AccessShareLock);
2737 ScanKeyInit(&key[0],
2738 Anum_pg_depend_refclassid,
2739 BTEqualStrategyNumber, F_OIDEQ,
2740 ObjectIdGetDatum(TypeRelationId));
2741 ScanKeyInit(&key[1],
2742 Anum_pg_depend_refobjid,
2743 BTEqualStrategyNumber, F_OIDEQ,
2744 ObjectIdGetDatum(typeOid));
2746 depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
2747 SnapshotNow, 2, key);
2749 while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
2751 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
2753 Form_pg_attribute att;
2755 /* Ignore dependees that aren't user columns of relations */
2756 /* (we assume system columns are never of rowtypes) */
2757 if (pg_depend->classid != RelationRelationId ||
2758 pg_depend->objsubid <= 0)
2761 rel = relation_open(pg_depend->objid, AccessShareLock);
2762 att = rel->rd_att->attrs[pg_depend->objsubid - 1];
2764 if (rel->rd_rel->relkind == RELKIND_RELATION)
2767 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2768 errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
2770 RelationGetRelationName(rel),
2771 NameStr(att->attname))));
2773 else if (OidIsValid(rel->rd_rel->reltype))
2776 * A view or composite type itself isn't a problem, but we
2777 * must recursively check for indirect dependencies via its
2780 find_composite_type_dependencies(rel->rd_rel->reltype,
2784 relation_close(rel, AccessShareLock);
2787 systable_endscan(depScan);
2789 relation_close(depRel, AccessShareLock);
2794 * ALTER TABLE ADD COLUMN
2796 * Adds an additional attribute to a relation making the assumption that
2797 * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
2798 * AT_AddColumn AlterTableCmd by analyze.c and added as independent
2802 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
2806 * Recurse to add the column to child classes, if requested.
2808 * We must recurse one level at a time, so that multiply-inheriting
2809 * children are visited the right number of times and end up with the
2810 * right attinhcount.
2814 AlterTableCmd *childCmd = copyObject(cmd);
2815 ColumnDef *colDefChild = (ColumnDef *) childCmd->def;
2817 /* Child should see column as singly inherited */
2818 colDefChild->inhcount = 1;
2819 colDefChild->is_local = false;
2820 /* and don't make a support dependency on the child */
2821 colDefChild->support = NULL;
2823 ATOneLevelRecursion(wqueue, rel, childCmd);
2828 * If we are told not to recurse, there had better not be any
2829 * child tables; else the addition would put them out of step.
2831 if (find_inheritance_children(RelationGetRelid(rel)) != NIL)
2833 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2834 errmsg("column must be added to child tables too")));
2839 ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
2842 Oid myrelid = RelationGetRelid(rel);
2846 HeapTuple attributeTuple;
2847 Form_pg_attribute attribute;
2848 FormData_pg_attribute attributeD;
2852 HeapTuple typeTuple;
2857 attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
2860 * Are we adding the column to a recursion child? If so, check
2861 * whether to merge with an existing definition for the column.
2863 if (colDef->inhcount > 0)
2867 /* Does child already have a column by this name? */
2868 tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
2869 if (HeapTupleIsValid(tuple))
2871 Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
2873 /* Okay if child matches by type */
2874 if (typenameTypeId(colDef->typename) != childatt->atttypid ||
2875 colDef->typename->typmod != childatt->atttypmod)
2877 (errcode(ERRCODE_DATATYPE_MISMATCH),
2878 errmsg("child table \"%s\" has different type for column \"%s\"",
2879 RelationGetRelationName(rel), colDef->colname)));
2881 /* Bump the existing child att's inhcount */
2882 childatt->attinhcount++;
2883 simple_heap_update(attrdesc, &tuple->t_self, tuple);
2884 CatalogUpdateIndexes(attrdesc, tuple);
2886 heap_freetuple(tuple);
2888 /* Inform the user about the merge */
2890 (errmsg("merging definition of column \"%s\" for child \"%s\"",
2891 colDef->colname, RelationGetRelationName(rel))));
2893 heap_close(attrdesc, RowExclusiveLock);
2898 pgclass = heap_open(RelationRelationId, RowExclusiveLock);
2900 reltup = SearchSysCacheCopy(RELOID,
2901 ObjectIdGetDatum(myrelid),
2903 if (!HeapTupleIsValid(reltup))
2904 elog(ERROR, "cache lookup failed for relation %u", myrelid);
2907 * this test is deliberately not attisdropped-aware, since if one
2908 * tries to add a column matching a dropped column name, it's gonna
2911 if (SearchSysCacheExists(ATTNAME,
2912 ObjectIdGetDatum(myrelid),
2913 PointerGetDatum(colDef->colname),
2916 (errcode(ERRCODE_DUPLICATE_COLUMN),
2917 errmsg("column \"%s\" of relation \"%s\" already exists",
2918 colDef->colname, RelationGetRelationName(rel))));
2920 minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
2921 maxatts = minattnum + 1;
2922 if (maxatts > MaxHeapAttributeNumber)
2924 (errcode(ERRCODE_TOO_MANY_COLUMNS),
2925 errmsg("tables can have at most %d columns",
2926 MaxHeapAttributeNumber)));
2929 typeTuple = typenameType(colDef->typename);
2930 tform = (Form_pg_type) GETSTRUCT(typeTuple);
2931 typeOid = HeapTupleGetOid(typeTuple);
2933 /* make sure datatype is legal for a column */
2934 CheckAttributeType(colDef->colname, typeOid);
2936 attributeTuple = heap_addheader(Natts_pg_attribute,
2938 ATTRIBUTE_TUPLE_SIZE,
2939 (void *) &attributeD);
2941 attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
2943 attribute->attrelid = myrelid;
2944 namestrcpy(&(attribute->attname), colDef->colname);
2945 attribute->atttypid = typeOid;
2946 attribute->attstattarget = -1;
2947 attribute->attlen = tform->typlen;
2948 attribute->attcacheoff = -1;
2949 attribute->atttypmod = colDef->typename->typmod;
2950 attribute->attnum = i;
2951 attribute->attbyval = tform->typbyval;
2952 attribute->attndims = list_length(colDef->typename->arrayBounds);
2953 attribute->attstorage = tform->typstorage;
2954 attribute->attalign = tform->typalign;
2955 attribute->attnotnull = colDef->is_not_null;
2956 attribute->atthasdef = false;
2957 attribute->attisdropped = false;
2958 attribute->attislocal = colDef->is_local;
2959 attribute->attinhcount = colDef->inhcount;
2961 ReleaseSysCache(typeTuple);
2963 simple_heap_insert(attrdesc, attributeTuple);
2965 /* Update indexes on pg_attribute */
2966 CatalogUpdateIndexes(attrdesc, attributeTuple);
2968 heap_close(attrdesc, RowExclusiveLock);
2971 * Update number of attributes in pg_class tuple
2973 ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
2975 simple_heap_update(pgclass, &reltup->t_self, reltup);
2977 /* keep catalog indexes current */
2978 CatalogUpdateIndexes(pgclass, reltup);
2980 heap_freetuple(reltup);
2982 heap_close(pgclass, RowExclusiveLock);
2984 /* Make the attribute's catalog entry visible */
2985 CommandCounterIncrement();
2988 * Store the DEFAULT, if any, in the catalogs
2990 if (colDef->raw_default)
2992 RawColumnDefault *rawEnt;
2994 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
2995 rawEnt->attnum = attribute->attnum;
2996 rawEnt->raw_default = copyObject(colDef->raw_default);
2999 * This function is intended for CREATE TABLE, so it processes a
3000 * _list_ of defaults, but we just do one.
3002 AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
3004 /* Make the additional catalog changes visible */
3005 CommandCounterIncrement();
3009 * Tell Phase 3 to fill in the default expression, if there is one.
3011 * If there is no default, Phase 3 doesn't have to do anything, because
3012 * that effectively means that the default is NULL. The heap tuple
3013 * access routines always check for attnum > # of attributes in tuple,
3014 * and return NULL if so, so without any modification of the tuple
3015 * data we will get the effect of NULL values in the new column.
3017 * An exception occurs when the new column is of a domain type: the
3018 * domain might have a NOT NULL constraint, or a check constraint that
3019 * indirectly rejects nulls. If there are any domain constraints then
3020 * we construct an explicit NULL default value that will be passed through
3021 * CoerceToDomain processing. (This is a tad inefficient, since it
3022 * causes rewriting the table which we really don't have to do, but
3023 * the present design of domain processing doesn't offer any simple way
3024 * of checking the constraints more directly.)
3026 * Note: we use build_column_default, and not just the cooked default
3027 * returned by AddRelationRawConstraints, so that the right thing
3028 * happens when a datatype's default applies.
3030 defval = (Expr *) build_column_default(rel, attribute->attnum);
3032 if (!defval && GetDomainConstraints(typeOid) != NIL)
3034 Oid basetype = getBaseType(typeOid);
3036 defval = (Expr *) makeNullConst(basetype);
3037 defval = (Expr *) coerce_to_target_type(NULL,
3041 colDef->typename->typmod,
3042 COERCION_ASSIGNMENT,
3043 COERCE_IMPLICIT_CAST);
3044 if (defval == NULL) /* should not happen */
3045 elog(ERROR, "failed to coerce base type to domain");
3050 NewColumnValue *newval;
3052 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
3053 newval->attnum = attribute->attnum;
3054 newval->expr = defval;
3056 tab->newvals = lappend(tab->newvals, newval);
3060 * Add needed dependency entries for the new column.
3062 add_column_datatype_dependency(myrelid, i, attribute->atttypid);
3063 if (colDef->support != NULL)
3064 add_column_support_dependency(myrelid, i, colDef->support);
3068 * Install a column's dependency on its datatype.
3071 add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
3073 ObjectAddress myself,
3076 myself.classId = RelationRelationId;
3077 myself.objectId = relid;
3078 myself.objectSubId = attnum;
3079 referenced.classId = TypeRelationId;
3080 referenced.objectId = typid;
3081 referenced.objectSubId = 0;
3082 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3086 * Install a dependency for a column's supporting relation (serial sequence).
3089 add_column_support_dependency(Oid relid, int32 attnum, RangeVar *support)
3091 ObjectAddress colobject,
3094 colobject.classId = RelationRelationId;
3095 colobject.objectId = relid;
3096 colobject.objectSubId = attnum;
3097 suppobject.classId = RelationRelationId;
3098 suppobject.objectId = RangeVarGetRelid(support, false);
3099 suppobject.objectSubId = 0;
3100 recordDependencyOn(&suppobject, &colobject, DEPENDENCY_INTERNAL);
3104 * ALTER TABLE ALTER COLUMN DROP NOT NULL
3107 ATExecDropNotNull(Relation rel, const char *colName)
3113 ListCell *indexoidscan;
3116 * lookup the attribute
3118 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3120 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3122 if (!HeapTupleIsValid(tuple))
3124 (errcode(ERRCODE_UNDEFINED_COLUMN),
3125 errmsg("column \"%s\" of relation \"%s\" does not exist",
3126 colName, RelationGetRelationName(rel))));
3128 attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
3130 /* Prevent them from altering a system attribute */
3133 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3134 errmsg("cannot alter system column \"%s\"",
3138 * Check that the attribute is not in a primary key
3141 /* Loop over all indexes on the relation */
3142 indexoidlist = RelationGetIndexList(rel);
3144 foreach(indexoidscan, indexoidlist)
3146 Oid indexoid = lfirst_oid(indexoidscan);
3147 HeapTuple indexTuple;
3148 Form_pg_index indexStruct;
3151 indexTuple = SearchSysCache(INDEXRELID,
3152 ObjectIdGetDatum(indexoid),
3154 if (!HeapTupleIsValid(indexTuple))
3155 elog(ERROR, "cache lookup failed for index %u", indexoid);
3156 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
3158 /* If the index is not a primary key, skip the check */
3159 if (indexStruct->indisprimary)
3162 * Loop over each attribute in the primary key and see if it
3163 * matches the to-be-altered attribute
3165 for (i = 0; i < indexStruct->indnatts; i++)
3167 if (indexStruct->indkey.values[i] == attnum)
3169 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3170 errmsg("column \"%s\" is in a primary key",
3175 ReleaseSysCache(indexTuple);
3178 list_free(indexoidlist);
3181 * Okay, actually perform the catalog change ... if needed
3183 if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
3185 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;
3187 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3189 /* keep the system catalog indexes current */
3190 CatalogUpdateIndexes(attr_rel, tuple);
3193 heap_close(attr_rel, RowExclusiveLock);
3197 * ALTER TABLE ALTER COLUMN SET NOT NULL
3200 ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
3201 const char *colName)
3206 NewConstraint *newcon;
3209 * lookup the attribute
3211 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3213 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3215 if (!HeapTupleIsValid(tuple))
3217 (errcode(ERRCODE_UNDEFINED_COLUMN),
3218 errmsg("column \"%s\" of relation \"%s\" does not exist",
3219 colName, RelationGetRelationName(rel))));
3221 attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
3223 /* Prevent them from altering a system attribute */
3226 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3227 errmsg("cannot alter system column \"%s\"",
3231 * Okay, actually perform the catalog change ... if needed
3233 if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
3235 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;
3237 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3239 /* keep the system catalog indexes current */
3240 CatalogUpdateIndexes(attr_rel, tuple);
3242 /* Tell Phase 3 to test the constraint */
3243 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
3244 newcon->contype = CONSTR_NOTNULL;
3245 newcon->attnum = attnum;
3246 newcon->name = "NOT NULL";
3248 tab->constraints = lappend(tab->constraints, newcon);
3251 heap_close(attr_rel, RowExclusiveLock);
3255 * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
3258 ATExecColumnDefault(Relation rel, const char *colName,
3264 * get the number of the attribute
3266 attnum = get_attnum(RelationGetRelid(rel), colName);
3267 if (attnum == InvalidAttrNumber)
3269 (errcode(ERRCODE_UNDEFINED_COLUMN),
3270 errmsg("column \"%s\" of relation \"%s\" does not exist",
3271 colName, RelationGetRelationName(rel))));
3273 /* Prevent them from altering a system attribute */
3276 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3277 errmsg("cannot alter system column \"%s\"",
3281 * Remove any old default for the column. We use RESTRICT here for
3282 * safety, but at present we do not expect anything to depend on the
3285 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
3290 RawColumnDefault *rawEnt;
3292 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
3293 rawEnt->attnum = attnum;
3294 rawEnt->raw_default = newDefault;
3297 * This function is intended for CREATE TABLE, so it processes a
3298 * _list_ of defaults, but we just do one.
3300 AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
3305 * ALTER TABLE ALTER COLUMN SET STATISTICS
3308 ATPrepSetStatistics(Relation rel, const char *colName, Node *flagValue)
3311 * We do our own permission checking because (a) we want to allow SET
3312 * STATISTICS on indexes (for expressional index columns), and (b) we
3313 * want to allow SET STATISTICS on system catalogs without requiring
3314 * allowSystemTableMods to be turned on.
3316 if (rel->rd_rel->relkind != RELKIND_RELATION &&
3317 rel->rd_rel->relkind != RELKIND_INDEX)
3319 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3320 errmsg("\"%s\" is not a table or index",
3321 RelationGetRelationName(rel))));
3323 /* Permissions checks */
3324 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
3325 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
3326 RelationGetRelationName(rel));
3330 ATExecSetStatistics(Relation rel, const char *colName, Node *newValue)
3333 Relation attrelation;
3335 Form_pg_attribute attrtuple;
3337 Assert(IsA(newValue, Integer));
3338 newtarget = intVal(newValue);
3341 * Limit target to a sane range
3346 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3347 errmsg("statistics target %d is too low",
3350 else if (newtarget > 1000)
3354 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3355 errmsg("lowering statistics target to %d",
3359 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
3361 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3363 if (!HeapTupleIsValid(tuple))
3365 (errcode(ERRCODE_UNDEFINED_COLUMN),
3366 errmsg("column \"%s\" of relation \"%s\" does not exist",
3367 colName, RelationGetRelationName(rel))));
3368 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
3370 if (attrtuple->attnum <= 0)
3372 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3373 errmsg("cannot alter system column \"%s\"",
3376 attrtuple->attstattarget = newtarget;
3378 simple_heap_update(attrelation, &tuple->t_self, tuple);
3380 /* keep system catalog indexes current */
3381 CatalogUpdateIndexes(attrelation, tuple);
3383 heap_freetuple(tuple);
3385 heap_close(attrelation, RowExclusiveLock);
3389 * ALTER TABLE ALTER COLUMN SET STORAGE
3392 ATExecSetStorage(Relation rel, const char *colName, Node *newValue)
3396 Relation attrelation;
3398 Form_pg_attribute attrtuple;
3400 Assert(IsA(newValue, String));
3401 storagemode = strVal(newValue);
3403 if (pg_strcasecmp(storagemode, "plain") == 0)
3405 else if (pg_strcasecmp(storagemode, "external") == 0)
3407 else if (pg_strcasecmp(storagemode, "extended") == 0)
3409 else if (pg_strcasecmp(storagemode, "main") == 0)
3414 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3415 errmsg("invalid storage type \"%s\"",
3417 newstorage = 0; /* keep compiler quiet */
3420 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
3422 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
3424 if (!HeapTupleIsValid(tuple))
3426 (errcode(ERRCODE_UNDEFINED_COLUMN),
3427 errmsg("column \"%s\" of relation \"%s\" does not exist",
3428 colName, RelationGetRelationName(rel))));
3429 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
3431 if (attrtuple->attnum <= 0)
3433 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3434 errmsg("cannot alter system column \"%s\"",
3438 * safety check: do not allow toasted storage modes unless column
3439 * datatype is TOAST-aware.
3441 if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
3442 attrtuple->attstorage = newstorage;
3445 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3446 errmsg("column data type %s can only have storage PLAIN",
3447 format_type_be(attrtuple->atttypid))));
3449 simple_heap_update(attrelation, &tuple->t_self, tuple);
3451 /* keep system catalog indexes current */
3452 CatalogUpdateIndexes(attrelation, tuple);
3454 heap_freetuple(tuple);
3456 heap_close(attrelation, RowExclusiveLock);
3461 * ALTER TABLE DROP COLUMN
3463 * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
3464 * because we have to decide at runtime whether to recurse or not depending
3465 * on whether attinhcount goes to zero or not. (We can't check this in a
3466 * static pre-pass because it won't handle multiple inheritance situations
3467 * correctly.) Since DROP COLUMN doesn't need to create any work queue
3468 * entries for Phase 3, it's okay to recurse internally in this routine
3469 * without considering the work queue.
3472 ATExecDropColumn(Relation rel, const char *colName,
3473 DropBehavior behavior,
3474 bool recurse, bool recursing)
3477 Form_pg_attribute targetatt;
3480 ObjectAddress object;
3482 /* At top level, permission check was done in ATPrepCmd, else do it */
3484 ATSimplePermissions(rel, false);
3487 * get the number of the attribute
3489 tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
3490 if (!HeapTupleIsValid(tuple))
3492 (errcode(ERRCODE_UNDEFINED_COLUMN),
3493 errmsg("column \"%s\" of relation \"%s\" does not exist",
3494 colName, RelationGetRelationName(rel))));
3495 targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
3497 attnum = targetatt->attnum;
3499 /* Can't drop a system attribute, except OID */
3500 if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
3502 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3503 errmsg("cannot drop system column \"%s\"",
3506 /* Don't drop inherited columns */
3507 if (targetatt->attinhcount > 0 && !recursing)
3509 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3510 errmsg("cannot drop inherited column \"%s\"",
3513 ReleaseSysCache(tuple);
3516 * Propagate to children as appropriate. Unlike most other ALTER
3517 * routines, we have to do this one level of recursion at a time; we
3518 * can't use find_all_inheritors to do it in one pass.
3520 children = find_inheritance_children(RelationGetRelid(rel));
3527 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
3528 foreach(child, children)
3530 Oid childrelid = lfirst_oid(child);
3532 Form_pg_attribute childatt;
3534 childrel = heap_open(childrelid, AccessExclusiveLock);
3536 tuple = SearchSysCacheCopyAttName(childrelid, colName);
3537 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
3538 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
3539 colName, childrelid);
3540 childatt = (Form_pg_attribute) GETSTRUCT(tuple);
3542 if (childatt->attinhcount <= 0) /* shouldn't happen */
3543 elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
3544 childrelid, colName);
3549 * If the child column has other definition sources, just
3550 * decrement its inheritance count; if not, recurse to
3553 if (childatt->attinhcount == 1 && !childatt->attislocal)
3555 /* Time to delete this child column, too */
3556 ATExecDropColumn(childrel, colName, behavior, true, true);
3560 /* Child column must survive my deletion */
3561 childatt->attinhcount--;
3563 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3565 /* keep the system catalog indexes current */
3566 CatalogUpdateIndexes(attr_rel, tuple);
3568 /* Make update visible */
3569 CommandCounterIncrement();
3575 * If we were told to drop ONLY in this table (no
3576 * recursion), we need to mark the inheritors' attribute
3577 * as locally defined rather than inherited.
3579 childatt->attinhcount--;
3580 childatt->attislocal = true;
3582 simple_heap_update(attr_rel, &tuple->t_self, tuple);
3584 /* keep the system catalog indexes current */
3585 CatalogUpdateIndexes(attr_rel, tuple);
3587 /* Make update visible */
3588 CommandCounterIncrement();
3591 heap_freetuple(tuple);
3593 heap_close(childrel, NoLock);
3595 heap_close(attr_rel, RowExclusiveLock);
3599 * Perform the actual column deletion
3601 object.classId = RelationRelationId;
3602 object.objectId = RelationGetRelid(rel);
3603 object.objectSubId = attnum;
3605 performDeletion(&object, behavior);
3608 * If we dropped the OID column, must adjust pg_class.relhasoids
3610 if (attnum == ObjectIdAttributeNumber)
3613 Form_pg_class tuple_class;
3615 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
3617 tuple = SearchSysCacheCopy(RELOID,
3618 ObjectIdGetDatum(RelationGetRelid(rel)),
3620 if (!HeapTupleIsValid(tuple))
3621 elog(ERROR, "cache lookup failed for relation %u",
3622 RelationGetRelid(rel));
3623 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
3625 tuple_class->relhasoids = false;
3626 simple_heap_update(class_rel, &tuple->t_self, tuple);
3628 /* Keep the catalog indexes up to date */
3629 CatalogUpdateIndexes(class_rel, tuple);
3631 heap_close(class_rel, RowExclusiveLock);
3636 * ALTER TABLE ADD INDEX
3638 * There is no such command in the grammar, but the parser converts UNIQUE
3639 * and PRIMARY KEY constraints into AT_AddIndex subcommands. This lets us
3640 * schedule creation of the index at the appropriate time during ALTER.
3643 ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
3644 IndexStmt *stmt, bool is_rebuild)
3650 Assert(IsA(stmt, IndexStmt));
3652 /* suppress schema rights check when rebuilding existing index */
3653 check_rights = !is_rebuild;
3654 /* skip index build if phase 3 will have to rewrite table anyway */
3655 skip_build = (tab->newvals != NIL);
3656 /* suppress notices when rebuilding existing index */
3659 DefineIndex(stmt->relation, /* relation */
3660 stmt->idxname, /* index name */
3661 InvalidOid, /* no predefined OID */
3662 stmt->accessMethod, /* am name */
3664 stmt->indexParams, /* parameters */
3665 (Expr *) stmt->whereClause,
3670 true, /* is_alter_table */
3677 * ALTER TABLE ADD CONSTRAINT
3680 ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
3682 switch (nodeTag(newConstraint))
3686 Constraint *constr = (Constraint *) newConstraint;
3689 * Currently, we only expect to see CONSTR_CHECK nodes
3690 * arriving here (see the preprocessing done in
3691 * parser/analyze.c). Use a switch anyway to make it
3692 * easier to add more code later.
3694 switch (constr->contype)
3702 * Call AddRelationRawConstraints to do the
3703 * work. It returns a list of cooked
3706 newcons = AddRelationRawConstraints(rel, NIL,
3707 list_make1(constr));
3708 /* Add each constraint to Phase 3's queue */
3709 foreach(lcon, newcons)
3711 CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
3712 NewConstraint *newcon;
3714 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
3715 newcon->name = ccon->name;
3716 newcon->contype = ccon->contype;
3717 newcon->attnum = ccon->attnum;
3718 /* ExecQual wants implicit-AND format */
3719 newcon->qual = (Node *)
3720 make_ands_implicit((Expr *) ccon->expr);
3722 tab->constraints = lappend(tab->constraints,
3728 elog(ERROR, "unrecognized constraint type: %d",
3729 (int) constr->contype);
3733 case T_FkConstraint:
3735 FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
3738 * Assign or validate constraint name
3740 if (fkconstraint->constr_name)
3742 if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
3743 RelationGetRelid(rel),
3744 RelationGetNamespace(rel),
3745 fkconstraint->constr_name))
3747 (errcode(ERRCODE_DUPLICATE_OBJECT),
3748 errmsg("constraint \"%s\" for relation \"%s\" already exists",
3749 fkconstraint->constr_name,
3750 RelationGetRelationName(rel))));
3753 fkconstraint->constr_name =
3754 ChooseConstraintName(RelationGetRelationName(rel),
3755 strVal(linitial(fkconstraint->fk_attrs)),
3757 RelationGetNamespace(rel),
3760 ATAddForeignKeyConstraint(tab, rel, fkconstraint);
3765 elog(ERROR, "unrecognized node type: %d",
3766 (int) nodeTag(newConstraint));
3771 * Add a foreign-key constraint to a single table
3773 * Subroutine for ATExecAddConstraint. Must already hold exclusive
3774 * lock on the rel, and have done appropriate validity/permissions checks
3778 ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
3779 FkConstraint *fkconstraint)
3782 AclResult aclresult;
3783 int16 pkattnum[INDEX_MAX_KEYS];
3784 int16 fkattnum[INDEX_MAX_KEYS];
3785 Oid pktypoid[INDEX_MAX_KEYS];
3786 Oid fktypoid[INDEX_MAX_KEYS];
3787 Oid opclasses[INDEX_MAX_KEYS];
3795 * Grab an exclusive lock on the pk table, so that someone doesn't
3796 * delete rows out from under us. (Although a lesser lock would do for
3797 * that purpose, we'll need exclusive lock anyway to add triggers to
3798 * the pk table; trying to start with a lesser lock will just create a
3799 * risk of deadlock.)
3801 pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
3804 * Validity and permissions checks
3806 * Note: REFERENCES permissions checks are redundant with CREATE TRIGGER,
3807 * but we may as well error out sooner instead of later.
3809 if (pkrel->rd_rel->relkind != RELKIND_RELATION)
3811 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3812 errmsg("referenced relation \"%s\" is not a table",
3813 RelationGetRelationName(pkrel))));
3815 aclresult = pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(),
3817 if (aclresult != ACLCHECK_OK)
3818 aclcheck_error(aclresult, ACL_KIND_CLASS,
3819 RelationGetRelationName(pkrel));
3821 if (!allowSystemTableMods && IsSystemRelation(pkrel))
3823 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3824 errmsg("permission denied: \"%s\" is a system catalog",
3825 RelationGetRelationName(pkrel))));
3827 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
3829 if (aclresult != ACLCHECK_OK)
3830 aclcheck_error(aclresult, ACL_KIND_CLASS,
3831 RelationGetRelationName(rel));
3834 * Disallow reference from permanent table to temp table or vice
3835 * versa. (The ban on perm->temp is for fairly obvious reasons. The
3836 * ban on temp->perm is because other backends might need to run the
3837 * RI triggers on the perm table, but they can't reliably see tuples
3838 * the owning backend has created in the temp table, because
3839 * non-shared buffers are used for temp tables.)
3841 if (isTempNamespace(RelationGetNamespace(pkrel)))
3843 if (!isTempNamespace(RelationGetNamespace(rel)))
3845 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3846 errmsg("cannot reference temporary table from permanent table constraint")));
3850 if (isTempNamespace(RelationGetNamespace(rel)))
3852 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3853 errmsg("cannot reference permanent table from temporary table constraint")));
3857 * Look up the referencing attributes to make sure they exist, and
3858 * record their attnums and type OIDs.
3860 MemSet(pkattnum, 0, sizeof(pkattnum));
3861 MemSet(fkattnum, 0, sizeof(fkattnum));
3862 MemSet(pktypoid, 0, sizeof(pktypoid));
3863 MemSet(fktypoid, 0, sizeof(fktypoid));
3864 MemSet(opclasses, 0, sizeof(opclasses));
3866 numfks = transformColumnNameList(RelationGetRelid(rel),
3867 fkconstraint->fk_attrs,
3868 fkattnum, fktypoid);
3871 * If the attribute list for the referenced table was omitted, lookup
3872 * the definition of the primary key and use it. Otherwise, validate
3873 * the supplied attribute list. In either case, discover the index
3874 * OID and index opclasses, and the attnums and type OIDs of the
3877 if (fkconstraint->pk_attrs == NIL)
3879 numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
3880 &fkconstraint->pk_attrs,
3886 numpks = transformColumnNameList(RelationGetRelid(pkrel),
3887 fkconstraint->pk_attrs,
3888 pkattnum, pktypoid);
3889 /* Look for an index matching the column list */
3890 indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
3894 /* Be sure referencing and referenced column types are comparable */
3895 if (numfks != numpks)
3897 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
3898 errmsg("number of referencing and referenced columns for foreign key disagree")));
3900 for (i = 0; i < numpks; i++)
3903 * pktypoid[i] is the primary key table's i'th key's type
3904 * fktypoid[i] is the foreign key table's i'th key's type
3906 * Note that we look for an operator with the PK type on the left;
3907 * when the types are different this is critical because the PK
3908 * index will need operators with the indexkey on the left.
3909 * (Ordinarily both commutator operators will exist if either
3910 * does, but we won't get the right answer from the test below on
3911 * opclass membership unless we select the proper operator.)
3913 Operator o = oper(list_make1(makeString("=")),
3914 pktypoid[i], fktypoid[i], true);
3918 (errcode(ERRCODE_UNDEFINED_FUNCTION),
3919 errmsg("foreign key constraint \"%s\" "
3920 "cannot be implemented",
3921 fkconstraint->constr_name),
3922 errdetail("Key columns \"%s\" and \"%s\" "
3923 "are of incompatible types: %s and %s.",
3924 strVal(list_nth(fkconstraint->fk_attrs, i)),
3925 strVal(list_nth(fkconstraint->pk_attrs, i)),
3926 format_type_be(fktypoid[i]),
3927 format_type_be(pktypoid[i]))));
3930 * Check that the found operator is compatible with the PK index,
3931 * and generate a warning if not, since otherwise costly seqscans
3932 * will be incurred to check FK validity.
3934 if (!op_in_opclass(oprid(o), opclasses[i]))
3936 (errmsg("foreign key constraint \"%s\" "
3937 "will require costly sequential scans",
3938 fkconstraint->constr_name),
3939 errdetail("Key columns \"%s\" and \"%s\" "
3940 "are of different types: %s and %s.",
3941 strVal(list_nth(fkconstraint->fk_attrs, i)),
3942 strVal(list_nth(fkconstraint->pk_attrs, i)),
3943 format_type_be(fktypoid[i]),
3944 format_type_be(pktypoid[i]))));
3950 * Tell Phase 3 to check that the constraint is satisfied by existing
3951 * rows (we can skip this during table creation).
3953 if (!fkconstraint->skip_validation)
3955 NewConstraint *newcon;
3957 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
3958 newcon->name = fkconstraint->constr_name;
3959 newcon->contype = CONSTR_FOREIGN;
3960 newcon->refrelid = RelationGetRelid(pkrel);
3961 newcon->qual = (Node *) fkconstraint;
3963 tab->constraints = lappend(tab->constraints, newcon);
3967 * Record the FK constraint in pg_constraint.
3969 constrOid = CreateConstraintEntry(fkconstraint->constr_name,
3970 RelationGetNamespace(rel),
3972 fkconstraint->deferrable,
3973 fkconstraint->initdeferred,
3974 RelationGetRelid(rel),
3977 InvalidOid, /* not a domain
3979 RelationGetRelid(pkrel),
3982 fkconstraint->fk_upd_action,
3983 fkconstraint->fk_del_action,
3984 fkconstraint->fk_matchtype,
3986 NULL, /* no check constraint */
3991 * Create the triggers that will enforce the constraint.
3993 createForeignKeyTriggers(rel, fkconstraint, constrOid);
3996 * Close pk table, but keep lock until we've committed.
3998 heap_close(pkrel, NoLock);
4003 * transformColumnNameList - transform list of column names
4005 * Lookup each name and return its attnum and type OID
4008 transformColumnNameList(Oid relId, List *colList,
4009 int16 *attnums, Oid *atttypids)
4017 char *attname = strVal(lfirst(l));
4020 atttuple = SearchSysCacheAttName(relId, attname);
4021 if (!HeapTupleIsValid(atttuple))
4023 (errcode(ERRCODE_UNDEFINED_COLUMN),
4024 errmsg("column \"%s\" referenced in foreign key constraint does not exist",
4026 if (attnum >= INDEX_MAX_KEYS)
4028 (errcode(ERRCODE_TOO_MANY_COLUMNS),
4029 errmsg("cannot have more than %d keys in a foreign key",
4031 attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
4032 atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
4033 ReleaseSysCache(atttuple);
4041 * transformFkeyGetPrimaryKey -
4043 * Look up the names, attnums, and types of the primary key attributes
4044 * for the pkrel. Also return the index OID and index opclasses of the
4045 * index supporting the primary key.
4047 * All parameters except pkrel are output parameters. Also, the function
4048 * return value is the number of attributes in the primary key.
4050 * Used when the column list in the REFERENCES specification is omitted.
4053 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
4055 int16 *attnums, Oid *atttypids,
4059 ListCell *indexoidscan;
4060 HeapTuple indexTuple = NULL;
4061 Form_pg_index indexStruct = NULL;
4062 Datum indclassDatum;
4064 oidvector *indclass;
4068 * Get the list of index OIDs for the table from the relcache, and
4069 * look up each one in the pg_index syscache until we find one marked
4070 * primary key (hopefully there isn't more than one such).
4072 indexoidlist = RelationGetIndexList(pkrel);
4074 foreach(indexoidscan, indexoidlist)
4076 Oid indexoid = lfirst_oid(indexoidscan);
4078 indexTuple = SearchSysCache(INDEXRELID,
4079 ObjectIdGetDatum(indexoid),
4081 if (!HeapTupleIsValid(indexTuple))
4082 elog(ERROR, "cache lookup failed for index %u", indexoid);
4083 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4084 if (indexStruct->indisprimary)
4086 *indexOid = indexoid;
4089 ReleaseSysCache(indexTuple);
4093 list_free(indexoidlist);
4096 * Check that we found it
4098 if (indexStruct == NULL)
4100 (errcode(ERRCODE_UNDEFINED_OBJECT),
4101 errmsg("there is no primary key for referenced table \"%s\"",
4102 RelationGetRelationName(pkrel))));
4104 /* Must get indclass the hard way */
4105 indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
4106 Anum_pg_index_indclass, &isnull);
4108 indclass = (oidvector *) DatumGetPointer(indclassDatum);
4111 * Now build the list of PK attributes from the indkey definition (we
4112 * assume a primary key cannot have expressional elements)
4115 for (i = 0; i < indexStruct->indnatts; i++)
4117 int pkattno = indexStruct->indkey.values[i];
4119 attnums[i] = pkattno;
4120 atttypids[i] = attnumTypeId(pkrel, pkattno);
4121 opclasses[i] = indclass->values[i];
4122 *attnamelist = lappend(*attnamelist,
4123 makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
4126 ReleaseSysCache(indexTuple);
4132 * transformFkeyCheckAttrs -
4134 * Make sure that the attributes of a referenced table belong to a unique
4135 * (or primary key) constraint. Return the OID of the index supporting
4136 * the constraint, as well as the opclasses associated with the index
4140 transformFkeyCheckAttrs(Relation pkrel,
4141 int numattrs, int16 *attnums,
4142 Oid *opclasses) /* output parameter */
4144 Oid indexoid = InvalidOid;
4147 ListCell *indexoidscan;
4150 * Get the list of index OIDs for the table from the relcache, and
4151 * look up each one in the pg_index syscache, and match unique indexes
4152 * to the list of attnums we are given.
4154 indexoidlist = RelationGetIndexList(pkrel);
4156 foreach(indexoidscan, indexoidlist)
4158 HeapTuple indexTuple;
4159 Form_pg_index indexStruct;
4163 indexoid = lfirst_oid(indexoidscan);
4164 indexTuple = SearchSysCache(INDEXRELID,
4165 ObjectIdGetDatum(indexoid),
4167 if (!HeapTupleIsValid(indexTuple))
4168 elog(ERROR, "cache lookup failed for index %u", indexoid);
4169 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4172 * Must have the right number of columns; must be unique and not a
4173 * partial index; forget it if there are any expressions, too
4175 if (indexStruct->indnatts == numattrs &&
4176 indexStruct->indisunique &&
4177 heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
4178 heap_attisnull(indexTuple, Anum_pg_index_indexprs))
4180 /* Must get indclass the hard way */
4181 Datum indclassDatum;
4183 oidvector *indclass;
4185 indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
4186 Anum_pg_index_indclass, &isnull);
4188 indclass = (oidvector *) DatumGetPointer(indclassDatum);
4191 * The given attnum list may match the index columns in any
4192 * order. Check that each list is a subset of the other.
4194 for (i = 0; i < numattrs; i++)
4197 for (j = 0; j < numattrs; j++)
4199 if (attnums[i] == indexStruct->indkey.values[j])
4210 for (i = 0; i < numattrs; i++)
4213 for (j = 0; j < numattrs; j++)
4215 if (attnums[j] == indexStruct->indkey.values[i])
4217 opclasses[j] = indclass->values[i];
4227 ReleaseSysCache(indexTuple);
4234 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
4235 errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
4236 RelationGetRelationName(pkrel))));
4238 list_free(indexoidlist);
4244 * Scan the existing rows in a table to verify they meet a proposed FK
4247 * Caller must have opened and locked both relations.
4250 validateForeignKeyConstraint(FkConstraint *fkconstraint,
4261 * See if we can do it with a single LEFT JOIN query. A FALSE result
4262 * indicates we must proceed with the fire-the-trigger method.
4264 if (RI_Initial_Check(fkconstraint, rel, pkrel))
4268 * Scan through each tuple, calling RI_FKey_check_ins (insert trigger)
4269 * as if that tuple had just been inserted. If any of those fail, it
4270 * should ereport(ERROR) and that's that.
4272 MemSet(&trig, 0, sizeof(trig));
4273 trig.tgoid = InvalidOid;
4274 trig.tgname = fkconstraint->constr_name;
4275 trig.tgenabled = TRUE;
4276 trig.tgisconstraint = TRUE;
4277 trig.tgconstrrelid = RelationGetRelid(pkrel);
4278 trig.tgdeferrable = FALSE;
4279 trig.tginitdeferred = FALSE;
4281 trig.tgargs = (char **) palloc(sizeof(char *) *
4282 (4 + list_length(fkconstraint->fk_attrs)
4283 + list_length(fkconstraint->pk_attrs)));
4285 trig.tgargs[0] = trig.tgname;
4286 trig.tgargs[1] = RelationGetRelationName(rel);
4287 trig.tgargs[2] = RelationGetRelationName(pkrel);
4288 trig.tgargs[3] = fkMatchTypeToString(fkconstraint->fk_matchtype);
4290 foreach(list, fkconstraint->fk_attrs)
4292 char *fk_at = strVal(lfirst(list));
4294 trig.tgargs[count] = fk_at;
4298 foreach(list, fkconstraint->pk_attrs)
4300 char *pk_at = strVal(lfirst(list));
4302 trig.tgargs[count] = pk_at;
4305 trig.tgnargs = count - 1;
4307 scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
4309 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4311 FunctionCallInfoData fcinfo;
4312 TriggerData trigdata;
4315 * Make a call to the trigger function
4317 * No parameters are passed, but we do set a context
4319 MemSet(&fcinfo, 0, sizeof(fcinfo));
4322 * We assume RI_FKey_check_ins won't look at flinfo...
4324 trigdata.type = T_TriggerData;
4325 trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
4326 trigdata.tg_relation = rel;
4327 trigdata.tg_trigtuple = tuple;
4328 trigdata.tg_newtuple = NULL;
4329 trigdata.tg_trigger = &trig;
4330 trigdata.tg_trigtuplebuf = scan->rs_cbuf;
4331 trigdata.tg_newtuplebuf = InvalidBuffer;
4333 fcinfo.context = (Node *) &trigdata;
4335 RI_FKey_check_ins(&fcinfo);
4344 CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
4345 ObjectAddress *constrobj, ObjectAddress *trigobj,
4348 CreateTrigStmt *fk_trigger;
4352 fk_trigger = makeNode(CreateTrigStmt);
4353 fk_trigger->trigname = fkconstraint->constr_name;
4354 fk_trigger->relation = myRel;
4355 fk_trigger->before = false;
4356 fk_trigger->row = true;
4358 /* Either ON INSERT or ON UPDATE */
4361 fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
4362 fk_trigger->actions[0] = 'i';
4366 fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
4367 fk_trigger->actions[0] = 'u';
4369 fk_trigger->actions[1] = '\0';
4371 fk_trigger->isconstraint = true;
4372 fk_trigger->deferrable = fkconstraint->deferrable;
4373 fk_trigger->initdeferred = fkconstraint->initdeferred;
4374 fk_trigger->constrrel = fkconstraint->pktable;
4376 fk_trigger->args = NIL;
4377 fk_trigger->args = lappend(fk_trigger->args,
4378 makeString(fkconstraint->constr_name));
4379 fk_trigger->args = lappend(fk_trigger->args,
4380 makeString(myRel->relname));
4381 fk_trigger->args = lappend(fk_trigger->args,
4382 makeString(fkconstraint->pktable->relname));
4383 fk_trigger->args = lappend(fk_trigger->args,
4384 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4385 if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
4387 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
4388 errmsg("number of referencing and referenced columns for foreign key disagree")));
4390 forboth(fk_attr, fkconstraint->fk_attrs,
4391 pk_attr, fkconstraint->pk_attrs)
4393 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4394 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4397 trigobj->objectId = CreateTrigger(fk_trigger, true);
4399 /* Register dependency from trigger to constraint */
4400 recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL);
4402 /* Make changes-so-far visible */
4403 CommandCounterIncrement();
4407 * Create the triggers that implement an FK constraint.
4410 createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
4414 CreateTrigStmt *fk_trigger;
4417 ObjectAddress trigobj,
4421 * Reconstruct a RangeVar for my relation (not passed in,
4424 myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
4425 pstrdup(RelationGetRelationName(rel)));
4428 * Preset objectAddress fields
4430 constrobj.classId = ConstraintRelationId;
4431 constrobj.objectId = constrOid;
4432 constrobj.objectSubId = 0;
4433 trigobj.classId = TriggerRelationId;
4434 trigobj.objectSubId = 0;
4436 /* Make changes-so-far visible */
4437 CommandCounterIncrement();
4440 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the
4441 * CHECK action for both INSERTs and UPDATEs on the referencing table.
4443 CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, true);
4444 CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, false);
4447 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
4448 * DELETE action on the referenced table.
4450 fk_trigger = makeNode(CreateTrigStmt);
4451 fk_trigger->trigname = fkconstraint->constr_name;
4452 fk_trigger->relation = fkconstraint->pktable;
4453 fk_trigger->before = false;
4454 fk_trigger->row = true;
4455 fk_trigger->actions[0] = 'd';
4456 fk_trigger->actions[1] = '\0';
4458 fk_trigger->isconstraint = true;
4459 fk_trigger->constrrel = myRel;
4460 switch (fkconstraint->fk_del_action)
4462 case FKCONSTR_ACTION_NOACTION:
4463 fk_trigger->deferrable = fkconstraint->deferrable;
4464 fk_trigger->initdeferred = fkconstraint->initdeferred;
4465 fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
4467 case FKCONSTR_ACTION_RESTRICT:
4468 fk_trigger->deferrable = false;
4469 fk_trigger->initdeferred = false;
4470 fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
4472 case FKCONSTR_ACTION_CASCADE:
4473 fk_trigger->deferrable = false;
4474 fk_trigger->initdeferred = false;
4475 fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
4477 case FKCONSTR_ACTION_SETNULL:
4478 fk_trigger->deferrable = false;
4479 fk_trigger->initdeferred = false;
4480 fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
4482 case FKCONSTR_ACTION_SETDEFAULT:
4483 fk_trigger->deferrable = false;
4484 fk_trigger->initdeferred = false;
4485 fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
4488 elog(ERROR, "unrecognized FK action type: %d",
4489 (int) fkconstraint->fk_del_action);
4493 fk_trigger->args = NIL;
4494 fk_trigger->args = lappend(fk_trigger->args,
4495 makeString(fkconstraint->constr_name));
4496 fk_trigger->args = lappend(fk_trigger->args,
4497 makeString(myRel->relname));
4498 fk_trigger->args = lappend(fk_trigger->args,
4499 makeString(fkconstraint->pktable->relname));
4500 fk_trigger->args = lappend(fk_trigger->args,
4501 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4502 forboth(fk_attr, fkconstraint->fk_attrs,
4503 pk_attr, fkconstraint->pk_attrs)
4505 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4506 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4509 trigobj.objectId = CreateTrigger(fk_trigger, true);
4511 /* Register dependency from trigger to constraint */
4512 recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
4514 /* Make changes-so-far visible */
4515 CommandCounterIncrement();
4518 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
4519 * UPDATE action on the referenced table.
4521 fk_trigger = makeNode(CreateTrigStmt);
4522 fk_trigger->trigname = fkconstraint->constr_name;
4523 fk_trigger->relation = fkconstraint->pktable;
4524 fk_trigger->before = false;
4525 fk_trigger->row = true;
4526 fk_trigger->actions[0] = 'u';
4527 fk_trigger->actions[1] = '\0';
4528 fk_trigger->isconstraint = true;
4529 fk_trigger->constrrel = myRel;
4530 switch (fkconstraint->fk_upd_action)
4532 case FKCONSTR_ACTION_NOACTION:
4533 fk_trigger->deferrable = fkconstraint->deferrable;
4534 fk_trigger->initdeferred = fkconstraint->initdeferred;
4535 fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
4537 case FKCONSTR_ACTION_RESTRICT:
4538 fk_trigger->deferrable = false;
4539 fk_trigger->initdeferred = false;
4540 fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
4542 case FKCONSTR_ACTION_CASCADE:
4543 fk_trigger->deferrable = false;
4544 fk_trigger->initdeferred = false;
4545 fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
4547 case FKCONSTR_ACTION_SETNULL:
4548 fk_trigger->deferrable = false;
4549 fk_trigger->initdeferred = false;
4550 fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
4552 case FKCONSTR_ACTION_SETDEFAULT:
4553 fk_trigger->deferrable = false;
4554 fk_trigger->initdeferred = false;
4555 fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
4558 elog(ERROR, "unrecognized FK action type: %d",
4559 (int) fkconstraint->fk_upd_action);
4563 fk_trigger->args = NIL;
4564 fk_trigger->args = lappend(fk_trigger->args,
4565 makeString(fkconstraint->constr_name));
4566 fk_trigger->args = lappend(fk_trigger->args,
4567 makeString(myRel->relname));
4568 fk_trigger->args = lappend(fk_trigger->args,
4569 makeString(fkconstraint->pktable->relname));
4570 fk_trigger->args = lappend(fk_trigger->args,
4571 makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
4572 forboth(fk_attr, fkconstraint->fk_attrs,
4573 pk_attr, fkconstraint->pk_attrs)
4575 fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
4576 fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
4579 trigobj.objectId = CreateTrigger(fk_trigger, true);
4581 /* Register dependency from trigger to constraint */
4582 recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
4586 * fkMatchTypeToString -
4587 * convert FKCONSTR_MATCH_xxx code to string to use in trigger args
4590 fkMatchTypeToString(char match_type)
4594 case FKCONSTR_MATCH_FULL:
4595 return pstrdup("FULL");
4596 case FKCONSTR_MATCH_PARTIAL:
4597 return pstrdup("PARTIAL");
4598 case FKCONSTR_MATCH_UNSPECIFIED:
4599 return pstrdup("UNSPECIFIED");
4601 elog(ERROR, "unrecognized match type: %d",
4604 return NULL; /* can't get here */
4608 * ALTER TABLE DROP CONSTRAINT
4611 ATPrepDropConstraint(List **wqueue, Relation rel,
4612 bool recurse, AlterTableCmd *cmd)
4615 * We don't want errors or noise from child tables, so we have to pass
4616 * down a modified command.
4620 AlterTableCmd *childCmd = copyObject(cmd);
4622 childCmd->subtype = AT_DropConstraintQuietly;
4623 ATSimpleRecursion(wqueue, rel, childCmd, recurse);
4628 ATExecDropConstraint(Relation rel, const char *constrName,
4629 DropBehavior behavior, bool quiet)
4633 deleted = RemoveRelConstraints(rel, constrName, behavior);
4637 /* If zero constraints deleted, complain */
4640 (errcode(ERRCODE_UNDEFINED_OBJECT),
4641 errmsg("constraint \"%s\" does not exist",
4643 /* Otherwise if more than one constraint deleted, notify */
4644 else if (deleted > 1)
4646 (errmsg("multiple constraints named \"%s\" were dropped",
4655 ATPrepAlterColumnType(List **wqueue,
4656 AlteredTableInfo *tab, Relation rel,
4657 bool recurse, bool recursing,
4660 char *colName = cmd->name;
4661 TypeName *typename = (TypeName *) cmd->def;
4663 Form_pg_attribute attTup;
4667 NewColumnValue *newval;
4668 ParseState *pstate = make_parsestate(NULL);
4670 /* lookup the attribute so we can check inheritance status */
4671 tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4672 if (!HeapTupleIsValid(tuple))
4674 (errcode(ERRCODE_UNDEFINED_COLUMN),
4675 errmsg("column \"%s\" of relation \"%s\" does not exist",
4676 colName, RelationGetRelationName(rel))));
4677 attTup = (Form_pg_attribute) GETSTRUCT(tuple);
4678 attnum = attTup->attnum;
4680 /* Can't alter a system attribute */
4683 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4684 errmsg("cannot alter system column \"%s\"",
4687 /* Don't alter inherited columns */
4688 if (attTup->attinhcount > 0 && !recursing)
4690 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4691 errmsg("cannot alter inherited column \"%s\"",
4694 /* Look up the target type */
4695 targettype = LookupTypeName(typename);
4696 if (!OidIsValid(targettype))
4698 (errcode(ERRCODE_UNDEFINED_OBJECT),
4699 errmsg("type \"%s\" does not exist",
4700 TypeNameToString(typename))));
4702 /* make sure datatype is legal for a column */
4703 CheckAttributeType(colName, targettype);
4706 * Set up an expression to transform the old data value to the new
4707 * type. If a USING option was given, transform and use that
4708 * expression, else just take the old value and try to coerce it. We
4709 * do this first so that type incompatibility can be detected before
4710 * we waste effort, and because we need the expression to be parsed
4711 * against the original table rowtype.
4717 /* Expression must be able to access vars of old table */
4718 rte = addRangeTableEntryForRelation(pstate,
4723 addRTEtoQuery(pstate, rte, false, true);
4725 transform = transformExpr(pstate, cmd->transform);
4727 /* It can't return a set */
4728 if (expression_returns_set(transform))
4730 (errcode(ERRCODE_DATATYPE_MISMATCH),
4731 errmsg("transform expression must not return a set")));
4733 /* No subplans or aggregates, either... */
4734 if (pstate->p_hasSubLinks)
4736 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4737 errmsg("cannot use subquery in transform expression")));
4738 if (pstate->p_hasAggs)
4740 (errcode(ERRCODE_GROUPING_ERROR),
4741 errmsg("cannot use aggregate function in transform expression")));
4745 transform = (Node *) makeVar(1, attnum,
4746 attTup->atttypid, attTup->atttypmod,
4750 transform = coerce_to_target_type(pstate,
4751 transform, exprType(transform),
4752 targettype, typename->typmod,
4753 COERCION_ASSIGNMENT,
4754 COERCE_IMPLICIT_CAST);
4755 if (transform == NULL)
4757 (errcode(ERRCODE_DATATYPE_MISMATCH),
4758 errmsg("column \"%s\" cannot be cast to type \"%s\"",
4759 colName, TypeNameToString(typename))));
4762 * Add a work queue item to make ATRewriteTable update the column
4765 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
4766 newval->attnum = attnum;
4767 newval->expr = (Expr *) transform;
4769 tab->newvals = lappend(tab->newvals, newval);
4771 ReleaseSysCache(tuple);
4774 * The recursion case is handled by ATSimpleRecursion. However, if we
4775 * are told not to recurse, there had better not be any child tables;
4776 * else the alter would put them out of step.
4779 ATSimpleRecursion(wqueue, rel, cmd, recurse);
4780 else if (!recursing &&
4781 find_inheritance_children(RelationGetRelid(rel)) != NIL)
4783 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4784 errmsg("type of inherited column \"%s\" must be changed in child tables too",
4789 ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
4790 const char *colName, TypeName *typename)
4793 Form_pg_attribute attTup;
4795 HeapTuple typeTuple;
4799 Relation attrelation;
4805 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4807 /* Look up the target column */
4808 heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4809 if (!HeapTupleIsValid(heapTup)) /* shouldn't happen */
4811 (errcode(ERRCODE_UNDEFINED_COLUMN),
4812 errmsg("column \"%s\" of relation \"%s\" does not exist",
4813 colName, RelationGetRelationName(rel))));
4814 attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
4815 attnum = attTup->attnum;
4817 /* Check for multiple ALTER TYPE on same column --- can't cope */
4818 if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
4819 attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
4821 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4822 errmsg("cannot alter type of column \"%s\" twice",
4825 /* Look up the target type (should not fail, since prep found it) */
4826 typeTuple = typenameType(typename);
4827 tform = (Form_pg_type) GETSTRUCT(typeTuple);
4828 targettype = HeapTupleGetOid(typeTuple);
4831 * If there is a default expression for the column, get it and ensure
4832 * we can coerce it to the new datatype. (We must do this before
4833 * changing the column type, because build_column_default itself will
4834 * try to coerce, and will not issue the error message we want if it
4837 * We remove any implicit coercion steps at the top level of the old
4838 * default expression; this has been agreed to satisfy the principle
4839 * of least surprise. (The conversion to the new column type should
4840 * act like it started from what the user sees as the stored expression,
4841 * and the implicit coercions aren't going to be shown.)
4843 if (attTup->atthasdef)
4845 defaultexpr = build_column_default(rel, attnum);
4846 Assert(defaultexpr);
4847 defaultexpr = strip_implicit_coercions(defaultexpr);
4848 defaultexpr = coerce_to_target_type(NULL, /* no UNKNOWN params */
4849 defaultexpr, exprType(defaultexpr),
4850 targettype, typename->typmod,
4851 COERCION_ASSIGNMENT,
4852 COERCE_IMPLICIT_CAST);
4853 if (defaultexpr == NULL)
4855 (errcode(ERRCODE_DATATYPE_MISMATCH),
4856 errmsg("default for column \"%s\" cannot be cast to type \"%s\"",
4857 colName, TypeNameToString(typename))));
4863 * Find everything that depends on the column (constraints, indexes,
4864 * etc), and record enough information to let us recreate the objects.
4866 * The actual recreation does not happen here, but only after we have
4867 * performed all the individual ALTER TYPE operations. We have to
4868 * save the info before executing ALTER TYPE, though, else the
4869 * deparser will get confused.
4871 * There could be multiple entries for the same object, so we must check
4872 * to ensure we process each one only once. Note: we assume that an
4873 * index that implements a constraint will not show a direct
4874 * dependency on the column.
4876 depRel = heap_open(DependRelationId, RowExclusiveLock);
4878 ScanKeyInit(&key[0],
4879 Anum_pg_depend_refclassid,
4880 BTEqualStrategyNumber, F_OIDEQ,
4881 ObjectIdGetDatum(RelationRelationId));
4882 ScanKeyInit(&key[1],
4883 Anum_pg_depend_refobjid,
4884 BTEqualStrategyNumber, F_OIDEQ,
4885 ObjectIdGetDatum(RelationGetRelid(rel)));
4886 ScanKeyInit(&key[2],
4887 Anum_pg_depend_refobjsubid,
4888 BTEqualStrategyNumber, F_INT4EQ,
4889 Int32GetDatum((int32) attnum));
4891 scan = systable_beginscan(depRel, DependReferenceIndexId, true,
4892 SnapshotNow, 3, key);
4894 while (HeapTupleIsValid(depTup = systable_getnext(scan)))
4896 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
4897 ObjectAddress foundObject;
4899 /* We don't expect any PIN dependencies on columns */
4900 if (foundDep->deptype == DEPENDENCY_PIN)
4901 elog(ERROR, "cannot alter type of a pinned column");
4903 foundObject.classId = foundDep->classid;
4904 foundObject.objectId = foundDep->objid;
4905 foundObject.objectSubId = foundDep->objsubid;
4907 switch (getObjectClass(&foundObject))
4911 char relKind = get_rel_relkind(foundObject.objectId);
4913 if (relKind == RELKIND_INDEX)
4915 Assert(foundObject.objectSubId == 0);
4916 if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
4918 tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
4919 foundObject.objectId);
4920 tab->changedIndexDefs = lappend(tab->changedIndexDefs,
4921 pg_get_indexdef_string(foundObject.objectId));
4924 else if (relKind == RELKIND_SEQUENCE)
4927 * This must be a SERIAL column's sequence. We
4928 * need not do anything to it.
4930 Assert(foundObject.objectSubId == 0);
4934 /* Not expecting any other direct dependencies... */
4935 elog(ERROR, "unexpected object depending on column: %s",
4936 getObjectDescription(&foundObject));
4941 case OCLASS_CONSTRAINT:
4942 Assert(foundObject.objectSubId == 0);
4943 if (!list_member_oid(tab->changedConstraintOids, foundObject.objectId))
4945 tab->changedConstraintOids = lappend_oid(tab->changedConstraintOids,
4946 foundObject.objectId);
4947 tab->changedConstraintDefs = lappend(tab->changedConstraintDefs,
4948 pg_get_constraintdef_string(foundObject.objectId));
4952 case OCLASS_REWRITE:
4953 /* XXX someday see if we can cope with revising views */
4955 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4956 errmsg("cannot alter type of a column used by a view or rule"),
4957 errdetail("%s depends on column \"%s\"",
4958 getObjectDescription(&foundObject),
4962 case OCLASS_DEFAULT:
4965 * Ignore the column's default expression, since we will
4968 Assert(defaultexpr);
4974 case OCLASS_CONVERSION:
4975 case OCLASS_LANGUAGE:
4976 case OCLASS_OPERATOR:
4977 case OCLASS_OPCLASS:
4978 case OCLASS_TRIGGER:
4982 * We don't expect any of these sorts of objects to depend
4985 elog(ERROR, "unexpected object depending on column: %s",
4986 getObjectDescription(&foundObject));
4990 elog(ERROR, "unrecognized object class: %u",
4991 foundObject.classId);
4995 systable_endscan(scan);
4998 * Now scan for dependencies of this column on other things. The only
4999 * thing we should find is the dependency on the column datatype,
5000 * which we want to remove.
5002 ScanKeyInit(&key[0],
5003 Anum_pg_depend_classid,
5004 BTEqualStrategyNumber, F_OIDEQ,
5005 ObjectIdGetDatum(RelationRelationId));
5006 ScanKeyInit(&key[1],
5007 Anum_pg_depend_objid,
5008 BTEqualStrategyNumber, F_OIDEQ,
5009 ObjectIdGetDatum(RelationGetRelid(rel)));
5010 ScanKeyInit(&key[2],
5011 Anum_pg_depend_objsubid,
5012 BTEqualStrategyNumber, F_INT4EQ,
5013 Int32GetDatum((int32) attnum));
5015 scan = systable_beginscan(depRel, DependDependerIndexId, true,
5016 SnapshotNow, 3, key);
5018 while (HeapTupleIsValid(depTup = systable_getnext(scan)))
5020 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
5022 if (foundDep->deptype != DEPENDENCY_NORMAL)
5023 elog(ERROR, "found unexpected dependency type '%c'",
5025 if (foundDep->refclassid != TypeRelationId ||
5026 foundDep->refobjid != attTup->atttypid)
5027 elog(ERROR, "found unexpected dependency for column");
5029 simple_heap_delete(depRel, &depTup->t_self);
5032 systable_endscan(scan);
5034 heap_close(depRel, RowExclusiveLock);
5037 * Here we go --- change the recorded column type. (Note heapTup is a
5038 * copy of the syscache entry, so okay to scribble on.)
5040 attTup->atttypid = targettype;
5041 attTup->atttypmod = typename->typmod;
5042 attTup->attndims = list_length(typename->arrayBounds);
5043 attTup->attlen = tform->typlen;
5044 attTup->attbyval = tform->typbyval;
5045 attTup->attalign = tform->typalign;
5046 attTup->attstorage = tform->typstorage;
5048 ReleaseSysCache(typeTuple);
5050 simple_heap_update(attrelation, &heapTup->t_self, heapTup);
5052 /* keep system catalog indexes current */
5053 CatalogUpdateIndexes(attrelation, heapTup);
5055 heap_close(attrelation, RowExclusiveLock);
5057 /* Install dependency on new datatype */
5058 add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
5061 * Drop any pg_statistic entry for the column, since it's now wrong
5064 RemoveStatistics(RelationGetRelid(rel), attnum);
5067 * Update the default, if present, by brute force --- remove and
5068 * re-add the default. Probably unsafe to take shortcuts, since the
5069 * new version may well have additional dependencies. (It's okay to
5070 * do this now, rather than after other ALTER TYPE commands, since the
5071 * default won't depend on other column types.)
5075 /* Must make new row visible since it will be updated again */
5076 CommandCounterIncrement();
5079 * We use RESTRICT here for safety, but at present we do not
5080 * expect anything to depend on the default.
5082 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
5084 StoreAttrDefault(rel, attnum, nodeToString(defaultexpr));
5088 heap_freetuple(heapTup);
5092 * Cleanup after we've finished all the ALTER TYPE operations for a
5093 * particular relation. We have to drop and recreate all the indexes
5094 * and constraints that depend on the altered columns.
5097 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
5103 * Re-parse the index and constraint definitions, and attach them to
5104 * the appropriate work queue entries. We do this before dropping
5105 * because in the case of a FOREIGN KEY constraint, we might not yet
5106 * have exclusive lock on the table the constraint is attached to, and
5107 * we need to get that before dropping. It's safe because the parser
5108 * won't actually look at the catalogs to detect the existing entry.
5110 foreach(l, tab->changedIndexDefs)
5111 ATPostAlterTypeParse((char *) lfirst(l), wqueue);
5112 foreach(l, tab->changedConstraintDefs)
5113 ATPostAlterTypeParse((char *) lfirst(l), wqueue);
5116 * Now we can drop the existing constraints and indexes ---
5117 * constraints first, since some of them might depend on the indexes.
5118 * It should be okay to use DROP_RESTRICT here, since nothing else
5119 * should be depending on these objects.
5121 foreach(l, tab->changedConstraintOids)
5123 obj.classId = ConstraintRelationId;
5124 obj.objectId = lfirst_oid(l);
5125 obj.objectSubId = 0;
5126 performDeletion(&obj, DROP_RESTRICT);
5129 foreach(l, tab->changedIndexOids)
5131 obj.classId = RelationRelationId;
5132 obj.objectId = lfirst_oid(l);
5133 obj.objectSubId = 0;
5134 performDeletion(&obj, DROP_RESTRICT);
5138 * The objects will get recreated during subsequent passes over the
5144 ATPostAlterTypeParse(char *cmd, List **wqueue)
5146 List *raw_parsetree_list;
5147 List *querytree_list;
5148 ListCell *list_item;
5151 * We expect that we only have to do raw parsing and parse analysis,
5152 * not any rule rewriting, since these will all be utility statements.
5154 raw_parsetree_list = raw_parser(cmd);
5155 querytree_list = NIL;
5156 foreach(list_item, raw_parsetree_list)
5158 Node *parsetree = (Node *) lfirst(list_item);
5160 querytree_list = list_concat(querytree_list,
5161 parse_analyze(parsetree, NULL, 0));
5165 * Attach each generated command to the proper place in the work
5166 * queue. Note this could result in creation of entirely new
5167 * work-queue entries.
5169 foreach(list_item, querytree_list)
5171 Query *query = (Query *) lfirst(list_item);
5173 AlteredTableInfo *tab;
5175 Assert(IsA(query, Query));
5176 Assert(query->commandType == CMD_UTILITY);
5177 switch (nodeTag(query->utilityStmt))
5181 IndexStmt *stmt = (IndexStmt *) query->utilityStmt;
5182 AlterTableCmd *newcmd;
5184 rel = relation_openrv(stmt->relation, AccessExclusiveLock);
5185 tab = ATGetQueueEntry(wqueue, rel);
5186 newcmd = makeNode(AlterTableCmd);
5187 newcmd->subtype = AT_ReAddIndex;
5188 newcmd->def = (Node *) stmt;
5189 tab->subcmds[AT_PASS_OLD_INDEX] =
5190 lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
5191 relation_close(rel, NoLock);
5194 case T_AlterTableStmt:
5196 AlterTableStmt *stmt = (AlterTableStmt *) query->utilityStmt;
5199 rel = relation_openrv(stmt->relation, AccessExclusiveLock);
5200 tab = ATGetQueueEntry(wqueue, rel);
5201 foreach(lcmd, stmt->cmds)
5203 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
5205 switch (cmd->subtype)
5208 cmd->subtype = AT_ReAddIndex;
5209 tab->subcmds[AT_PASS_OLD_INDEX] =
5210 lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
5212 case AT_AddConstraint:
5213 tab->subcmds[AT_PASS_OLD_CONSTR] =
5214 lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
5217 elog(ERROR, "unexpected statement type: %d",
5218 (int) cmd->subtype);
5221 relation_close(rel, NoLock);
5225 elog(ERROR, "unexpected statement type: %d",
5226 (int) nodeTag(query->utilityStmt));
5236 ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5238 Relation target_rel;
5241 Form_pg_class tuple_class;
5244 * Get exclusive lock till end of transaction on the target table.
5245 * Use relation_open so that we can work on indexes and sequences.
5247 target_rel = relation_open(relationOid, AccessExclusiveLock);
5249 /* Get its pg_class tuple, too */
5250 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5252 tuple = SearchSysCache(RELOID,
5253 ObjectIdGetDatum(relationOid),
5255 if (!HeapTupleIsValid(tuple))
5256 elog(ERROR, "cache lookup failed for relation %u", relationOid);
5257 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
5259 /* Can we change the ownership of this tuple? */
5260 switch (tuple_class->relkind)
5262 case RELKIND_RELATION:
5265 case RELKIND_SEQUENCE:
5266 case RELKIND_TOASTVALUE:
5267 /* ok to change owner */
5271 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5272 errmsg("\"%s\" is not a table, TOAST table, index, view, or sequence",
5273 NameStr(tuple_class->relname))));
5277 * If the new owner is the same as the existing owner, consider the
5278 * command to have succeeded. This is for dump restoration purposes.
5280 if (tuple_class->relowner != newOwnerSysId)
5282 Datum repl_val[Natts_pg_class];
5283 char repl_null[Natts_pg_class];
5284 char repl_repl[Natts_pg_class];
5290 /* Otherwise, check that we are the superuser */
5293 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5294 errmsg("must be superuser to change owner")));
5296 memset(repl_null, ' ', sizeof(repl_null));
5297 memset(repl_repl, ' ', sizeof(repl_repl));
5299 repl_repl[Anum_pg_class_relowner - 1] = 'r';
5300 repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSysId);
5303 * Determine the modified ACL for the new owner. This is only
5304 * necessary when the ACL is non-null.
5306 aclDatum = SysCacheGetAttr(RELOID, tuple,
5307 Anum_pg_class_relacl,
5311 newAcl = aclnewowner(DatumGetAclP(aclDatum),
5312 tuple_class->relowner, newOwnerSysId);
5313 repl_repl[Anum_pg_class_relacl - 1] = 'r';
5314 repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
5317 newtuple = heap_modifytuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl);
5319 simple_heap_update(class_rel, &newtuple->t_self, newtuple);
5320 CatalogUpdateIndexes(class_rel, newtuple);
5322 heap_freetuple(newtuple);
5325 * If we are operating on a table, also change the ownership of
5326 * any indexes and sequences that belong to the table, as well as
5327 * the table's toast table (if it has one)
5329 if (tuple_class->relkind == RELKIND_RELATION ||
5330 tuple_class->relkind == RELKIND_TOASTVALUE)
5332 List *index_oid_list;
5335 /* Find all the indexes belonging to this relation */
5336 index_oid_list = RelationGetIndexList(target_rel);
5338 /* For each index, recursively change its ownership */
5339 foreach(i, index_oid_list)
5340 ATExecChangeOwner(lfirst_oid(i), newOwnerSysId);
5342 list_free(index_oid_list);
5345 if (tuple_class->relkind == RELKIND_RELATION)
5347 /* If it has a toast table, recurse to change its ownership */
5348 if (tuple_class->reltoastrelid != InvalidOid)
5349 ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
5351 /* If it has dependent sequences, recurse to change them too */
5352 change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
5356 ReleaseSysCache(tuple);
5357 heap_close(class_rel, RowExclusiveLock);
5358 relation_close(target_rel, NoLock);
5362 * change_owner_recurse_to_sequences
5364 * Helper function for ATExecChangeOwner. Examines pg_depend searching
5365 * for sequences that are dependent on serial columns, and changes their
5369 change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
5377 * SERIAL sequences are those having an internal dependency on one
5378 * of the table's columns (we don't care *which* column, exactly).
5380 depRel = heap_open(DependRelationId, AccessShareLock);
5382 ScanKeyInit(&key[0],
5383 Anum_pg_depend_refclassid,
5384 BTEqualStrategyNumber, F_OIDEQ,
5385 ObjectIdGetDatum(RelationRelationId));
5386 ScanKeyInit(&key[1],
5387 Anum_pg_depend_refobjid,
5388 BTEqualStrategyNumber, F_OIDEQ,
5389 ObjectIdGetDatum(relationOid));
5390 /* we leave refobjsubid unspecified */
5392 scan = systable_beginscan(depRel, DependReferenceIndexId, true,
5393 SnapshotNow, 2, key);
5395 while (HeapTupleIsValid(tup = systable_getnext(scan)))
5397 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
5400 /* skip dependencies other than internal dependencies on columns */
5401 if (depForm->refobjsubid == 0 ||
5402 depForm->classid != RelationRelationId ||
5403 depForm->objsubid != 0 ||
5404 depForm->deptype != DEPENDENCY_INTERNAL)
5407 /* Use relation_open just in case it's an index */
5408 seqRel = relation_open(depForm->objid, AccessExclusiveLock);
5410 /* skip non-sequence relations */
5411 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
5413 /* No need to keep the lock */
5414 relation_close(seqRel, AccessExclusiveLock);
5418 /* We don't need to close the sequence while we alter it. */
5419 ATExecChangeOwner(depForm->objid, newOwnerSysId);
5421 /* Now we can close it. Keep the lock till end of transaction. */
5422 relation_close(seqRel, NoLock);
5425 systable_endscan(scan);
5427 relation_close(depRel, AccessShareLock);
5431 * ALTER TABLE CLUSTER ON
5433 * The only thing we have to do is to change the indisclustered bits.
5436 ATExecClusterOn(Relation rel, const char *indexName)
5440 indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
5442 if (!OidIsValid(indexOid))
5444 (errcode(ERRCODE_UNDEFINED_OBJECT),
5445 errmsg("index \"%s\" for table \"%s\" does not exist",
5446 indexName, RelationGetRelationName(rel))));
5448 /* Check index is valid to cluster on */
5449 check_index_is_clusterable(rel, indexOid, false);
5451 /* And do the work */
5452 mark_index_clustered(rel, indexOid);
5456 * ALTER TABLE SET WITHOUT CLUSTER
5458 * We have to find any indexes on the table that have indisclustered bit
5459 * set and turn it off.
5462 ATExecDropCluster(Relation rel)
5464 mark_index_clustered(rel, InvalidOid);
5468 * ALTER TABLE SET TABLESPACE
5471 ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
5474 AclResult aclresult;
5477 * We do our own permission checking because we want to allow this on
5480 if (rel->rd_rel->relkind != RELKIND_RELATION &&
5481 rel->rd_rel->relkind != RELKIND_INDEX)
5483 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5484 errmsg("\"%s\" is not a table or index",
5485 RelationGetRelationName(rel))));
5487 /* Permissions checks */
5488 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
5489 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
5490 RelationGetRelationName(rel));
5492 if (!allowSystemTableMods && IsSystemRelation(rel))
5494 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5495 errmsg("permission denied: \"%s\" is a system catalog",
5496 RelationGetRelationName(rel))));
5498 /* Check that the tablespace exists */
5499 tablespaceId = get_tablespace_oid(tablespacename);
5500 if (!OidIsValid(tablespaceId))
5502 (errcode(ERRCODE_UNDEFINED_OBJECT),
5503 errmsg("tablespace \"%s\" does not exist", tablespacename)));
5505 /* Check its permissions */
5506 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
5507 if (aclresult != ACLCHECK_OK)
5508 aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
5510 /* Save info for Phase 3 to do the real work */
5511 if (OidIsValid(tab->newTableSpace))
5513 (errcode(ERRCODE_SYNTAX_ERROR),
5514 errmsg("cannot have multiple SET TABLESPACE subcommands")));
5515 tab->newTableSpace = tablespaceId;
5519 * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
5520 * rewriting to be done, so we just want to copy the data as fast as possible.
5523 ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
5529 RelFileNode newrnode;
5530 SMgrRelation dstrel;
5533 Form_pg_class rd_rel;
5535 rel = relation_open(tableOid, NoLock);
5538 * We can never allow moving of shared or nailed-in-cache relations,
5539 * because we can't support changing their reltablespace values.
5541 if (rel->rd_rel->relisshared || rel->rd_isnailed)
5543 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5544 errmsg("cannot move system relation \"%s\"",
5545 RelationGetRelationName(rel))));
5548 * Don't allow moving temp tables of other backends ... their local
5549 * buffer manager is not going to cope.
5551 if (isOtherTempNamespace(RelationGetNamespace(rel)))
5553 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5554 errmsg("cannot move temporary tables of other sessions")));
5557 * No work if no change in tablespace.
5559 oldTableSpace = rel->rd_rel->reltablespace;
5560 if (newTableSpace == oldTableSpace ||
5561 (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
5563 relation_close(rel, NoLock);
5567 reltoastrelid = rel->rd_rel->reltoastrelid;
5568 reltoastidxid = rel->rd_rel->reltoastidxid;
5570 /* Get a modifiable copy of the relation's pg_class row */
5571 pg_class = heap_open(RelationRelationId, RowExclusiveLock);
5573 tuple = SearchSysCacheCopy(RELOID,
5574 ObjectIdGetDatum(tableOid),
5576 if (!HeapTupleIsValid(tuple))
5577 elog(ERROR, "cache lookup failed for relation %u", tableOid);
5578 rd_rel = (Form_pg_class) GETSTRUCT(tuple);
5580 /* create another storage file. Is it a little ugly ? */
5581 /* NOTE: any conflict in relfilenode value will be caught here */
5582 newrnode = rel->rd_node;
5583 newrnode.spcNode = newTableSpace;
5585 dstrel = smgropen(newrnode);
5586 smgrcreate(dstrel, rel->rd_istemp, false);
5588 /* copy relation data to the new physical file */
5589 copy_relation_data(rel, dstrel);
5591 /* schedule unlinking old physical file */
5592 RelationOpenSmgr(rel);
5593 smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
5596 * Now drop smgr references. The source was already dropped by
5597 * smgrscheduleunlink.
5601 /* update the pg_class row */
5602 rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
5603 simple_heap_update(pg_class, &tuple->t_self, tuple);
5604 CatalogUpdateIndexes(pg_class, tuple);
5606 heap_freetuple(tuple);
5608 heap_close(pg_class, RowExclusiveLock);
5610 relation_close(rel, NoLock);
5612 /* Make sure the reltablespace change is visible */
5613 CommandCounterIncrement();
5615 /* Move associated toast relation and/or index, too */
5616 if (OidIsValid(reltoastrelid))
5617 ATExecSetTableSpace(reltoastrelid, newTableSpace);
5618 if (OidIsValid(reltoastidxid))
5619 ATExecSetTableSpace(reltoastidxid, newTableSpace);
5623 * Copy data, block by block
5626 copy_relation_data(Relation rel, SMgrRelation dst)
5630 BlockNumber nblocks;
5633 Page page = (Page) buf;
5636 * Since we copy the file directly without looking at the shared
5637 * buffers, we'd better first flush out any pages of the source
5638 * relation that are in shared buffers. We assume no new changes
5639 * will be made while we are holding exclusive lock on the rel.
5641 FlushRelationBuffers(rel);
5644 * We need to log the copied data in WAL iff WAL archiving is enabled
5645 * AND it's not a temp rel.
5647 use_wal = XLogArchivingActive() && !rel->rd_istemp;
5649 nblocks = RelationGetNumberOfBlocks(rel);
5650 /* RelationGetNumberOfBlocks will certainly have opened rd_smgr */
5653 for (blkno = 0; blkno < nblocks; blkno++)
5655 smgrread(src, blkno, buf);
5660 xl_heap_newpage xlrec;
5662 XLogRecData rdata[2];
5664 /* NO ELOG(ERROR) from here till newpage op is logged */
5665 START_CRIT_SECTION();
5667 xlrec.node = dst->smgr_rnode;
5668 xlrec.blkno = blkno;
5670 rdata[0].buffer = InvalidBuffer;
5671 rdata[0].data = (char *) &xlrec;
5672 rdata[0].len = SizeOfHeapNewpage;
5673 rdata[0].next = &(rdata[1]);
5675 rdata[1].buffer = InvalidBuffer;
5676 rdata[1].data = (char *) page;
5677 rdata[1].len = BLCKSZ;
5678 rdata[1].next = NULL;
5680 recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
5682 PageSetLSN(page, recptr);
5683 PageSetTLI(page, ThisTimeLineID);
5689 * Now write the page. We say isTemp = true even if it's not a
5690 * temp rel, because there's no need for smgr to schedule an fsync
5691 * for this write; we'll do it ourselves below.
5693 smgrwrite(dst, blkno, buf, true);
5697 * If the rel isn't temp, we must fsync it down to disk before it's
5698 * safe to commit the transaction. (For a temp rel we don't care
5699 * since the rel will be uninteresting after a crash anyway.)
5701 * It's obvious that we must do this when not WAL-logging the copy. It's
5702 * less obvious that we have to do it even if we did WAL-log the
5703 * copied pages. The reason is that since we're copying outside
5704 * shared buffers, a CHECKPOINT occurring during the copy has no way
5705 * to flush the previously written data to disk (indeed it won't know
5706 * the new rel even exists). A crash later on would replay WAL from
5707 * the checkpoint, therefore it wouldn't replay our earlier WAL
5708 * entries. If we do not fsync those pages here, they might still not
5709 * be on disk when the crash occurs.
5711 if (!rel->rd_istemp)
5716 * ALTER TABLE CREATE TOAST TABLE
5718 * Note: this is also invoked from outside this module; in such cases we
5719 * expect the caller to have verified that the relation is a table and we
5720 * have all the right permissions. Callers expect this function
5721 * to end with CommandCounterIncrement if it makes any changes.
5724 AlterTableCreateToastTable(Oid relOid, bool silent)
5729 bool shared_relation;
5733 char toast_relname[NAMEDATALEN];
5734 char toast_idxname[NAMEDATALEN];
5735 IndexInfo *indexInfo;
5736 Oid classObjectId[2];
5737 ObjectAddress baseobject,
5741 * Grab an exclusive lock on the target table, which we will NOT
5742 * release until end of transaction. (This is probably redundant in
5743 * all present uses...)
5745 rel = heap_open(relOid, AccessExclusiveLock);
5748 * Toast table is shared if and only if its parent is.
5750 * We cannot allow toasting a shared relation after initdb (because
5751 * there's no way to mark it toasted in other databases' pg_class).
5752 * Unfortunately we can't distinguish initdb from a manually started
5753 * standalone backend (toasting happens after the bootstrap phase, so
5754 * checking IsBootstrapProcessingMode() won't work). However, we can
5755 * at least prevent this mistake under normal multi-user operation.
5757 shared_relation = rel->rd_rel->relisshared;
5758 if (shared_relation && IsUnderPostmaster)
5760 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5761 errmsg("shared tables cannot be toasted after initdb")));
5764 * Is it already toasted?
5766 if (rel->rd_rel->reltoastrelid != InvalidOid)
5770 heap_close(rel, NoLock);
5775 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5776 errmsg("table \"%s\" already has a TOAST table",
5777 RelationGetRelationName(rel))));
5781 * Check to see whether the table actually needs a TOAST table.
5783 if (!needs_toast_table(rel))
5787 heap_close(rel, NoLock);
5792 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5793 errmsg("table \"%s\" does not need a TOAST table",
5794 RelationGetRelationName(rel))));
5798 * Create the toast table and its index
5800 snprintf(toast_relname, sizeof(toast_relname),
5801 "pg_toast_%u", relOid);
5802 snprintf(toast_idxname, sizeof(toast_idxname),
5803 "pg_toast_%u_index", relOid);
5805 /* this is pretty painful... need a tuple descriptor */
5806 tupdesc = CreateTemplateTupleDesc(3, false);
5807 TupleDescInitEntry(tupdesc, (AttrNumber) 1,
5811 TupleDescInitEntry(tupdesc, (AttrNumber) 2,
5815 TupleDescInitEntry(tupdesc, (AttrNumber) 3,
5821 * Ensure that the toast table doesn't itself get toasted, or we'll be
5822 * toast :-(. This is essential for chunk_data because type bytea is
5823 * toastable; hit the other two just to be sure.
5825 tupdesc->attrs[0]->attstorage = 'p';
5826 tupdesc->attrs[1]->attstorage = 'p';
5827 tupdesc->attrs[2]->attstorage = 'p';
5830 * Note: the toast relation is placed in the regular pg_toast
5831 * namespace even if its master relation is a temp table. There
5832 * cannot be any naming collision, and the toast rel will be destroyed
5833 * when its master is, so there's no need to handle the toast rel as
5836 toast_relid = heap_create_with_catalog(toast_relname,
5838 rel->rd_rel->reltablespace,
5848 /* make the toast relation visible, else index creation will fail */
5849 CommandCounterIncrement();
5852 * Create unique index on chunk_id, chunk_seq.
5854 * NOTE: the normal TOAST access routines could actually function with a
5855 * single-column index on chunk_id only. However, the slice access
5856 * routines use both columns for faster access to an individual chunk.
5857 * In addition, we want it to be unique as a check against the
5858 * possibility of duplicate TOAST chunk OIDs. The index might also be
5859 * a little more efficient this way, since btree isn't all that happy
5860 * with large numbers of equal keys.
5863 indexInfo = makeNode(IndexInfo);
5864 indexInfo->ii_NumIndexAttrs = 2;
5865 indexInfo->ii_KeyAttrNumbers[0] = 1;
5866 indexInfo->ii_KeyAttrNumbers[1] = 2;
5867 indexInfo->ii_Expressions = NIL;
5868 indexInfo->ii_ExpressionsState = NIL;
5869 indexInfo->ii_Predicate = NIL;
5870 indexInfo->ii_PredicateState = NIL;
5871 indexInfo->ii_Unique = true;
5873 classObjectId[0] = OID_BTREE_OPS_OID;
5874 classObjectId[1] = INT4_BTREE_OPS_OID;
5876 toast_idxid = index_create(toast_relid, toast_idxname, InvalidOid,
5879 rel->rd_rel->reltablespace,
5881 true, false, true, false);
5884 * Update toast rel's pg_class entry to show that it has an index. The
5885 * index OID is stored into the reltoastidxid field for easy access by
5886 * the tuple toaster.
5888 setRelhasindex(toast_relid, true, true, toast_idxid);
5891 * Store the toast table's OID in the parent relation's pg_class row
5893 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5895 reltup = SearchSysCacheCopy(RELOID,
5896 ObjectIdGetDatum(relOid),
5898 if (!HeapTupleIsValid(reltup))
5899 elog(ERROR, "cache lookup failed for relation %u", relOid);
5901 ((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
5903 simple_heap_update(class_rel, &reltup->t_self, reltup);
5905 /* Keep catalog indexes current */
5906 CatalogUpdateIndexes(class_rel, reltup);
5908 heap_freetuple(reltup);
5910 heap_close(class_rel, RowExclusiveLock);
5913 * Register dependency from the toast table to the master, so that the
5914 * toast table will be deleted if the master is.
5916 baseobject.classId = RelationRelationId;
5917 baseobject.objectId = relOid;
5918 baseobject.objectSubId = 0;
5919 toastobject.classId = RelationRelationId;
5920 toastobject.objectId = toast_relid;
5921 toastobject.objectSubId = 0;
5923 recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
5926 * Clean up and make changes visible
5928 heap_close(rel, NoLock);
5930 CommandCounterIncrement();
5934 * Check to see whether the table needs a TOAST table. It does only if
5935 * (1) there are any toastable attributes, and (2) the maximum length
5936 * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
5937 * create a toast table for something like "f1 varchar(20)".)
5940 needs_toast_table(Relation rel)
5942 int32 data_length = 0;
5943 bool maxlength_unknown = false;
5944 bool has_toastable_attrs = false;
5946 Form_pg_attribute *att;
5950 tupdesc = rel->rd_att;
5951 att = tupdesc->attrs;
5953 for (i = 0; i < tupdesc->natts; i++)
5955 if (att[i]->attisdropped)
5957 data_length = att_align(data_length, att[i]->attalign);
5958 if (att[i]->attlen > 0)
5960 /* Fixed-length types are never toastable */
5961 data_length += att[i]->attlen;
5965 int32 maxlen = type_maximum_size(att[i]->atttypid,
5969 maxlength_unknown = true;
5971 data_length += maxlen;
5972 if (att[i]->attstorage != 'p')
5973 has_toastable_attrs = true;
5976 if (!has_toastable_attrs)
5977 return false; /* nothing to toast? */
5978 if (maxlength_unknown)
5979 return true; /* any unlimited-length attrs? */
5980 tuple_length = MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) +
5981 BITMAPLEN(tupdesc->natts)) +
5982 MAXALIGN(data_length);
5983 return (tuple_length > TOAST_TUPLE_THRESHOLD);
5988 * This code supports
5989 * CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
5991 * Because we only support this for TEMP tables, it's sufficient to remember
5992 * the state in a backend-local data structure.
5996 * Register a newly-created relation's ON COMMIT action.
5999 register_on_commit_action(Oid relid, OnCommitAction action)
6002 MemoryContext oldcxt;
6005 * We needn't bother registering the relation unless there is an ON
6006 * COMMIT action we need to take.
6008 if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
6011 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
6013 oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
6015 oc->oncommit = action;
6016 oc->creating_subid = GetCurrentSubTransactionId();
6017 oc->deleting_subid = InvalidSubTransactionId;
6019 on_commits = lcons(oc, on_commits);
6021 MemoryContextSwitchTo(oldcxt);
6025 * Unregister any ON COMMIT action when a relation is deleted.
6027 * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
6030 remove_on_commit_action(Oid relid)
6034 foreach(l, on_commits)
6036 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
6038 if (oc->relid == relid)
6040 oc->deleting_subid = GetCurrentSubTransactionId();
6047 * Perform ON COMMIT actions.
6049 * This is invoked just before actually committing, since it's possible
6050 * to encounter errors.
6053 PreCommit_on_commit_actions(void)
6056 List *oids_to_truncate = NIL;
6058 foreach(l, on_commits)
6060 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
6062 /* Ignore entry if already dropped in this xact */
6063 if (oc->deleting_subid != InvalidSubTransactionId)
6066 switch (oc->oncommit)
6069 case ONCOMMIT_PRESERVE_ROWS:
6070 /* Do nothing (there shouldn't be such entries, actually) */
6072 case ONCOMMIT_DELETE_ROWS:
6073 oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
6077 ObjectAddress object;
6079 object.classId = RelationRelationId;
6080 object.objectId = oc->relid;
6081 object.objectSubId = 0;
6082 performDeletion(&object, DROP_CASCADE);
6085 * Note that table deletion will call
6086 * remove_on_commit_action, so the entry should get
6087 * marked as deleted.
6089 Assert(oc->deleting_subid != InvalidSubTransactionId);
6094 if (oids_to_truncate != NIL)
6096 heap_truncate(oids_to_truncate);
6097 CommandCounterIncrement(); /* XXX needed? */
6102 * Post-commit or post-abort cleanup for ON COMMIT management.
6104 * All we do here is remove no-longer-needed OnCommitItem entries.
6106 * During commit, remove entries that were deleted during this transaction;
6107 * during abort, remove those created during this transaction.
6110 AtEOXact_on_commit_actions(bool isCommit)
6113 ListCell *prev_item;
6116 cur_item = list_head(on_commits);
6118 while (cur_item != NULL)
6120 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
6122 if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
6123 oc->creating_subid != InvalidSubTransactionId)
6125 /* cur_item must be removed */
6126 on_commits = list_delete_cell(on_commits, cur_item, prev_item);
6129 cur_item = lnext(prev_item);
6131 cur_item = list_head(on_commits);
6135 /* cur_item must be preserved */
6136 oc->creating_subid = InvalidSubTransactionId;
6137 oc->deleting_subid = InvalidSubTransactionId;
6138 prev_item = cur_item;
6139 cur_item = lnext(prev_item);
6145 * Post-subcommit or post-subabort cleanup for ON COMMIT management.
6147 * During subabort, we can immediately remove entries created during this
6148 * subtransaction. During subcommit, just relabel entries marked during
6149 * this subtransaction as being the parent's responsibility.
6152 AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
6153 SubTransactionId parentSubid)
6156 ListCell *prev_item;
6159 cur_item = list_head(on_commits);
6161 while (cur_item != NULL)
6163 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
6165 if (!isCommit && oc->creating_subid == mySubid)
6167 /* cur_item must be removed */
6168 on_commits = list_delete_cell(on_commits, cur_item, prev_item);
6171 cur_item = lnext(prev_item);
6173 cur_item = list_head(on_commits);
6177 /* cur_item must be preserved */
6178 if (oc->creating_subid == mySubid)
6179 oc->creating_subid = parentSubid;
6180 if (oc->deleting_subid == mySubid)
6181 oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
6182 prev_item = cur_item;
6183 cur_item = lnext(prev_item);