1 /*-------------------------------------------------------------------------
4 * Commands for creating and altering table structures and settings
6 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/commands/tablecmds.c
13 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "access/reloptions.h"
20 #include "access/relscan.h"
21 #include "access/sysattr.h"
22 #include "access/xact.h"
23 #include "catalog/catalog.h"
24 #include "catalog/dependency.h"
25 #include "catalog/heap.h"
26 #include "catalog/index.h"
27 #include "catalog/indexing.h"
28 #include "catalog/namespace.h"
29 #include "catalog/objectaccess.h"
30 #include "catalog/pg_collation.h"
31 #include "catalog/pg_constraint.h"
32 #include "catalog/pg_depend.h"
33 #include "catalog/pg_foreign_table.h"
34 #include "catalog/pg_inherits.h"
35 #include "catalog/pg_inherits_fn.h"
36 #include "catalog/pg_namespace.h"
37 #include "catalog/pg_opclass.h"
38 #include "catalog/pg_tablespace.h"
39 #include "catalog/pg_trigger.h"
40 #include "catalog/pg_type.h"
41 #include "catalog/pg_type_fn.h"
42 #include "catalog/storage.h"
43 #include "catalog/toasting.h"
44 #include "commands/cluster.h"
45 #include "commands/comment.h"
46 #include "commands/defrem.h"
47 #include "commands/sequence.h"
48 #include "commands/tablecmds.h"
49 #include "commands/tablespace.h"
50 #include "commands/trigger.h"
51 #include "commands/typecmds.h"
52 #include "executor/executor.h"
53 #include "foreign/foreign.h"
54 #include "miscadmin.h"
55 #include "nodes/makefuncs.h"
56 #include "nodes/nodeFuncs.h"
57 #include "nodes/parsenodes.h"
58 #include "optimizer/clauses.h"
59 #include "parser/parse_clause.h"
60 #include "parser/parse_coerce.h"
61 #include "parser/parse_collate.h"
62 #include "parser/parse_expr.h"
63 #include "parser/parse_oper.h"
64 #include "parser/parse_relation.h"
65 #include "parser/parse_type.h"
66 #include "parser/parse_utilcmd.h"
67 #include "parser/parser.h"
68 #include "rewrite/rewriteDefine.h"
69 #include "rewrite/rewriteHandler.h"
70 #include "storage/bufmgr.h"
71 #include "storage/lmgr.h"
72 #include "storage/lock.h"
73 #include "storage/smgr.h"
74 #include "utils/acl.h"
75 #include "utils/builtins.h"
76 #include "utils/fmgroids.h"
77 #include "utils/inval.h"
78 #include "utils/lsyscache.h"
79 #include "utils/memutils.h"
80 #include "utils/relcache.h"
81 #include "utils/snapmgr.h"
82 #include "utils/syscache.h"
83 #include "utils/tqual.h"
84 #include "utils/typcache.h"
88 * ON COMMIT action list
90 typedef struct OnCommitItem
92 Oid relid; /* relid of relation */
93 OnCommitAction oncommit; /* what to do at end of xact */
96 * If this entry was created during the current transaction,
97 * creating_subid is the ID of the creating subxact; if created in a prior
98 * transaction, creating_subid is zero. If deleted during the current
99 * transaction, deleting_subid is the ID of the deleting subxact; if no
100 * deletion request is pending, deleting_subid is zero.
102 SubTransactionId creating_subid;
103 SubTransactionId deleting_subid;
106 static List *on_commits = NIL;
110 * State information for ALTER TABLE
112 * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
113 * structs, one for each table modified by the operation (the named table
114 * plus any child tables that are affected). We save lists of subcommands
115 * to apply to this table (possibly modified by parse transformation steps);
116 * these lists will be executed in Phase 2. If a Phase 3 step is needed,
117 * necessary information is stored in the constraints and newvals lists.
119 * Phase 2 is divided into multiple passes; subcommands are executed in
120 * a pass determined by subcommand type.
123 #define AT_PASS_DROP 0 /* DROP (all flavors) */
124 #define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */
125 #define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */
126 #define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints */
127 #define AT_PASS_COL_ATTRS 4 /* set other column attributes */
128 /* We could support a RENAME COLUMN pass here, but not currently used */
129 #define AT_PASS_ADD_COL 5 /* ADD COLUMN */
130 #define AT_PASS_ADD_INDEX 6 /* ADD indexes */
131 #define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */
132 #define AT_PASS_MISC 8 /* other stuff */
133 #define AT_NUM_PASSES 9
135 typedef struct AlteredTableInfo
137 /* Information saved before any work commences: */
138 Oid relid; /* Relation to work on */
139 char relkind; /* Its relkind */
140 TupleDesc oldDesc; /* Pre-modification tuple descriptor */
141 /* Information saved by Phase 1 for Phase 2: */
142 List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
143 /* Information saved by Phases 1/2 for Phase 3: */
144 List *constraints; /* List of NewConstraint */
145 List *newvals; /* List of NewColumnValue */
146 bool new_notnull; /* T if we added new NOT NULL constraints */
147 bool rewrite; /* T if a rewrite is forced */
148 Oid newTableSpace; /* new tablespace; 0 means no change */
149 /* Objects to rebuild after completing ALTER TYPE operations */
150 List *changedConstraintOids; /* OIDs of constraints to rebuild */
151 List *changedConstraintDefs; /* string definitions of same */
152 List *changedIndexOids; /* OIDs of indexes to rebuild */
153 List *changedIndexDefs; /* string definitions of same */
156 /* Struct describing one new constraint to check in Phase 3 scan */
157 /* Note: new NOT NULL constraints are handled elsewhere */
158 typedef struct NewConstraint
160 char *name; /* Constraint name, or NULL if none */
161 ConstrType contype; /* CHECK or FOREIGN */
162 Oid refrelid; /* PK rel, if FOREIGN */
163 Oid refindid; /* OID of PK's index, if FOREIGN */
164 Oid conid; /* OID of pg_constraint entry, if FOREIGN */
165 Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */
166 List *qualstate; /* Execution state for CHECK */
170 * Struct describing one new column value that needs to be computed during
171 * Phase 3 copy (this could be either a new column with a non-null default, or
172 * a column that we're changing the type of). Columns without such an entry
173 * are just copied from the old table during ATRewriteTable. Note that the
174 * expr is an expression over *old* table values.
176 typedef struct NewColumnValue
178 AttrNumber attnum; /* which column */
179 Expr *expr; /* expression to compute */
180 ExprState *exprstate; /* execution state */
184 * Error-reporting support for RemoveRelations
186 struct dropmsgstrings
189 int nonexistent_code;
190 const char *nonexistent_msg;
191 const char *skipping_msg;
192 const char *nota_msg;
193 const char *drophint_msg;
196 static const struct dropmsgstrings dropmsgstringarray[] = {
198 ERRCODE_UNDEFINED_TABLE,
199 gettext_noop("table \"%s\" does not exist"),
200 gettext_noop("table \"%s\" does not exist, skipping"),
201 gettext_noop("\"%s\" is not a table"),
202 gettext_noop("Use DROP TABLE to remove a table.")},
204 ERRCODE_UNDEFINED_TABLE,
205 gettext_noop("sequence \"%s\" does not exist"),
206 gettext_noop("sequence \"%s\" does not exist, skipping"),
207 gettext_noop("\"%s\" is not a sequence"),
208 gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
210 ERRCODE_UNDEFINED_TABLE,
211 gettext_noop("view \"%s\" does not exist"),
212 gettext_noop("view \"%s\" does not exist, skipping"),
213 gettext_noop("\"%s\" is not a view"),
214 gettext_noop("Use DROP VIEW to remove a view.")},
216 ERRCODE_UNDEFINED_OBJECT,
217 gettext_noop("index \"%s\" does not exist"),
218 gettext_noop("index \"%s\" does not exist, skipping"),
219 gettext_noop("\"%s\" is not an index"),
220 gettext_noop("Use DROP INDEX to remove an index.")},
221 {RELKIND_COMPOSITE_TYPE,
222 ERRCODE_UNDEFINED_OBJECT,
223 gettext_noop("type \"%s\" does not exist"),
224 gettext_noop("type \"%s\" does not exist, skipping"),
225 gettext_noop("\"%s\" is not a type"),
226 gettext_noop("Use DROP TYPE to remove a type.")},
227 {RELKIND_FOREIGN_TABLE,
228 ERRCODE_UNDEFINED_OBJECT,
229 gettext_noop("foreign table \"%s\" does not exist"),
230 gettext_noop("foreign table \"%s\" does not exist, skipping"),
231 gettext_noop("\"%s\" is not a foreign table"),
232 gettext_noop("Use DROP FOREIGN TABLE to remove a foreign table.")},
233 {'\0', 0, NULL, NULL, NULL, NULL}
236 /* Alter table target-type flags for ATSimplePermissions */
237 #define ATT_TABLE 0x0001
238 #define ATT_VIEW 0x0002
239 #define ATT_INDEX 0x0004
240 #define ATT_COMPOSITE_TYPE 0x0008
241 #define ATT_FOREIGN_TABLE 0x0010
243 static void truncate_check_rel(Relation rel);
244 static List *MergeAttributes(List *schema, List *supers, char relpersistence,
245 List **supOids, List **supconstr, int *supOidCount);
246 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
247 static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
248 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
249 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
250 static void StoreCatalogInheritance(Oid relationId, List *supers);
251 static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
252 int16 seqNumber, Relation inhRelation);
253 static int findAttrByName(const char *attributeName, List *schema);
254 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
255 static void AlterIndexNamespaces(Relation classRel, Relation rel,
256 Oid oldNspOid, Oid newNspOid);
257 static void AlterSeqNamespaces(Relation classRel, Relation rel,
258 Oid oldNspOid, Oid newNspOid,
259 const char *newNspName, LOCKMODE lockmode);
260 static void ATExecValidateConstraint(Relation rel, const char *constrName);
261 static int transformColumnNameList(Oid relId, List *colList,
262 int16 *attnums, Oid *atttypids);
263 static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
265 int16 *attnums, Oid *atttypids,
267 static Oid transformFkeyCheckAttrs(Relation pkrel,
268 int numattrs, int16 *attnums,
270 static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts);
271 static void validateForeignKeyConstraint(char *conname,
272 Relation rel, Relation pkrel,
273 Oid pkindOid, Oid constraintOid);
274 static void createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
275 Oid constraintOid, Oid indexOid);
276 static void ATController(Relation rel, List *cmds, bool recurse, LOCKMODE lockmode);
277 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
278 bool recurse, bool recursing, LOCKMODE lockmode);
279 static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode);
280 static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
281 AlterTableCmd *cmd, LOCKMODE lockmode);
282 static void ATRewriteTables(List **wqueue, LOCKMODE lockmode);
283 static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode);
284 static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
285 static void ATSimplePermissions(Relation rel, int allowed_targets);
286 static void ATWrongRelkindError(Relation rel, int allowed_targets);
287 static void ATSimpleRecursion(List **wqueue, Relation rel,
288 AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode);
289 static void ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
291 static List *find_typed_table_dependencies(Oid typeOid, const char *typeName,
292 DropBehavior behavior);
293 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
294 AlterTableCmd *cmd, LOCKMODE lockmode);
295 static void ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
296 ColumnDef *colDef, bool isOid,
297 bool recurse, bool recursing, LOCKMODE lockmode);
298 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
299 static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid);
300 static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
301 AlterTableCmd *cmd, LOCKMODE lockmode);
302 static void ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode);
303 static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
304 const char *colName, LOCKMODE lockmode);
305 static void ATExecColumnDefault(Relation rel, const char *colName,
306 Node *newDefault, LOCKMODE lockmode);
307 static void ATPrepSetStatistics(Relation rel, const char *colName,
308 Node *newValue, LOCKMODE lockmode);
309 static void ATExecSetStatistics(Relation rel, const char *colName,
310 Node *newValue, LOCKMODE lockmode);
311 static void ATExecSetOptions(Relation rel, const char *colName,
312 Node *options, bool isReset, LOCKMODE lockmode);
313 static void ATExecSetStorage(Relation rel, const char *colName,
314 Node *newValue, LOCKMODE lockmode);
315 static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
316 AlterTableCmd *cmd, LOCKMODE lockmode);
317 static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
318 DropBehavior behavior,
319 bool recurse, bool recursing,
320 bool missing_ok, LOCKMODE lockmode);
321 static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
322 IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode);
323 static void ATExecAddConstraint(List **wqueue,
324 AlteredTableInfo *tab, Relation rel,
325 Constraint *newConstraint, bool recurse, LOCKMODE lockmode);
326 static void ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
327 IndexStmt *stmt, LOCKMODE lockmode);
328 static void ATAddCheckConstraint(List **wqueue,
329 AlteredTableInfo *tab, Relation rel,
331 bool recurse, bool recursing, LOCKMODE lockmode);
332 static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
333 Constraint *fkconstraint, LOCKMODE lockmode);
334 static void ATExecDropConstraint(Relation rel, const char *constrName,
335 DropBehavior behavior,
336 bool recurse, bool recursing,
337 bool missing_ok, LOCKMODE lockmode);
338 static void ATPrepAlterColumnType(List **wqueue,
339 AlteredTableInfo *tab, Relation rel,
340 bool recurse, bool recursing,
341 AlterTableCmd *cmd, LOCKMODE lockmode);
342 static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
343 static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
344 AlterTableCmd *cmd, LOCKMODE lockmode);
345 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode);
346 static void ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode);
347 static void change_owner_recurse_to_sequences(Oid relationOid,
348 Oid newOwnerId, LOCKMODE lockmode);
349 static void ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode);
350 static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
351 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
352 char *tablespacename, LOCKMODE lockmode);
353 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
354 static void ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode);
355 static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
356 char fires_when, bool skip_system, LOCKMODE lockmode);
357 static void ATExecEnableDisableRule(Relation rel, char *rulename,
358 char fires_when, LOCKMODE lockmode);
359 static void ATPrepAddInherit(Relation child_rel);
360 static void ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
361 static void ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
362 static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid);
363 static void ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
364 static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
365 static void ATExecGenericOptions(Relation rel, List *options);
367 static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
368 ForkNumber forkNum, char relpersistence);
369 static const char *storage_name(char c);
372 /* ----------------------------------------------------------------
374 * Creates a new relation.
376 * stmt carries parsetree information from an ordinary CREATE TABLE statement.
377 * The other arguments are used to extend the behavior for other cases:
378 * relkind: relkind to assign to the new relation
379 * ownerId: if not InvalidOid, use this as the new relation's owner.
381 * Note that permissions checks are done against current user regardless of
382 * ownerId. A nonzero ownerId is used when someone is creating a relation
383 * "on behalf of" someone else, so we still want to see that the current user
384 * has permissions to do it.
386 * If successful, returns the OID of the new relation.
387 * ----------------------------------------------------------------
390 DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
392 char relname[NAMEDATALEN];
394 List *schema = stmt->tableElts;
398 TupleDesc descriptor;
400 List *old_constraints;
404 List *cookedDefaults;
408 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
412 * Truncate relname to appropriate length (probably a waste of time, as
413 * parser should have done this already).
415 StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
418 * Check consistency of arguments
420 if (stmt->oncommit != ONCOMMIT_NOOP
421 && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
423 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
424 errmsg("ON COMMIT can only be used on temporary tables")));
425 if (stmt->constraints != NIL && relkind == RELKIND_FOREIGN_TABLE)
427 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
428 errmsg("constraints on foreign tables are not supported")));
431 * Security check: disallow creating temp tables from security-restricted
432 * code. This is needed because calling code might not expect untrusted
433 * tables to appear in pg_temp at the front of its search path.
435 if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP
436 && InSecurityRestrictedOperation())
438 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
439 errmsg("cannot create temporary table within security-restricted operation")));
442 * Look up the namespace in which we are supposed to create the relation,
443 * and check we have permission to create there.
445 namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation);
448 * Select tablespace to use. If not specified, use default tablespace
449 * (which may in turn default to database's default).
451 if (stmt->tablespacename)
453 tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
457 tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence);
458 /* note InvalidOid is OK in this case */
461 /* Check permissions except when using database's default */
462 if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
466 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
468 if (aclresult != ACLCHECK_OK)
469 aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
470 get_tablespace_name(tablespaceId));
473 /* In all cases disallow placing user relations in pg_global */
474 if (tablespaceId == GLOBALTABLESPACE_OID)
476 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
477 errmsg("only shared relations can be placed in pg_global tablespace")));
479 /* Identify user ID that will own the table */
480 if (!OidIsValid(ownerId))
481 ownerId = GetUserId();
484 * Parse and validate reloptions, if any.
486 reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
489 (void) heap_reloptions(relkind, reloptions, true);
491 if (stmt->ofTypename)
492 ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
494 ofTypeId = InvalidOid;
497 * Look up inheritance ancestors and generate relation schema, including
498 * inherited attributes.
500 schema = MergeAttributes(schema, stmt->inhRelations,
501 stmt->relation->relpersistence,
502 &inheritOids, &old_constraints, &parentOidCount);
505 * Create a tuple descriptor from the relation schema. Note that this
506 * deals with column names, types, and NOT NULL constraints, but not
507 * default values or CHECK constraints; we handle those below.
509 descriptor = BuildDescForRelation(schema);
511 localHasOids = interpretOidsOption(stmt->options);
512 descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
515 * Find columns with default values and prepare for insertion of the
516 * defaults. Pre-cooked (that is, inherited) defaults go into a list of
517 * CookedConstraint structs that we'll pass to heap_create_with_catalog,
518 * while raw defaults go into a list of RawColumnDefault structs that will
519 * be processed by AddRelationNewConstraints. (We can't deal with raw
520 * expressions until we can do transformExpr.)
522 * We can set the atthasdef flags now in the tuple descriptor; this just
523 * saves StoreAttrDefault from having to do an immediate update of the
527 cookedDefaults = NIL;
530 foreach(listptr, schema)
532 ColumnDef *colDef = lfirst(listptr);
536 if (colDef->raw_default != NULL)
538 RawColumnDefault *rawEnt;
540 if (relkind == RELKIND_FOREIGN_TABLE)
542 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
543 errmsg("default values on foreign tables are not supported")));
545 Assert(colDef->cooked_default == NULL);
547 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
548 rawEnt->attnum = attnum;
549 rawEnt->raw_default = colDef->raw_default;
550 rawDefaults = lappend(rawDefaults, rawEnt);
551 descriptor->attrs[attnum - 1]->atthasdef = true;
553 else if (colDef->cooked_default != NULL)
555 CookedConstraint *cooked;
557 cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
558 cooked->contype = CONSTR_DEFAULT;
560 cooked->attnum = attnum;
561 cooked->expr = colDef->cooked_default;
562 cooked->is_local = true; /* not used for defaults */
563 cooked->inhcount = 0; /* ditto */
564 cookedDefaults = lappend(cookedDefaults, cooked);
565 descriptor->attrs[attnum - 1]->atthasdef = true;
570 * Create the relation. Inherited defaults and constraints are passed in
571 * for immediate handling --- since they don't need parsing, they can be
572 * stored immediately.
574 relationId = heap_create_with_catalog(relname,
582 list_concat(cookedDefaults,
585 stmt->relation->relpersistence,
593 allowSystemTableMods);
595 /* Store inheritance information for new rel. */
596 StoreCatalogInheritance(relationId, inheritOids);
599 * We must bump the command counter to make the newly-created relation
600 * tuple visible for opening.
602 CommandCounterIncrement();
605 * Open the new relation and acquire exclusive lock on it. This isn't
606 * really necessary for locking out other backends (since they can't see
607 * the new rel anyway until we commit), but it keeps the lock manager from
608 * complaining about deadlock risks.
610 rel = relation_open(relationId, AccessExclusiveLock);
613 * Now add any newly specified column default values and CHECK constraints
614 * to the new relation. These are passed to us in the form of raw
615 * parsetrees; we need to transform them to executable expression trees
616 * before they can be added. The most convenient way to do that is to
617 * apply the parser's transformExpr routine, but transformExpr doesn't
618 * work unless we have a pre-existing relation. So, the transformation has
619 * to be postponed to this final step of CREATE TABLE.
621 if (rawDefaults || stmt->constraints)
622 AddRelationNewConstraints(rel, rawDefaults, stmt->constraints,
626 * Clean up. We keep lock on new relation (although it shouldn't be
627 * visible to anyone else anyway, until commit).
629 relation_close(rel, NoLock);
635 * Emit the right error or warning message for a "DROP" command issued on a
636 * non-existent relation
639 DropErrorMsgNonExistent(const char *relname, char rightkind, bool missing_ok)
641 const struct dropmsgstrings *rentry;
643 for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
645 if (rentry->kind == rightkind)
650 (errcode(rentry->nonexistent_code),
651 errmsg(rentry->nonexistent_msg, relname)));
655 ereport(NOTICE, (errmsg(rentry->skipping_msg, relname)));
661 Assert(rentry->kind != '\0'); /* Should be impossible */
665 * Emit the right error message for a "DROP" command issued on a
666 * relation of the wrong type
669 DropErrorMsgWrongType(const char *relname, char wrongkind, char rightkind)
671 const struct dropmsgstrings *rentry;
672 const struct dropmsgstrings *wentry;
674 for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
675 if (rentry->kind == rightkind)
677 Assert(rentry->kind != '\0');
679 for (wentry = dropmsgstringarray; wentry->kind != '\0'; wentry++)
680 if (wentry->kind == wrongkind)
682 /* wrongkind could be something we don't have in our table... */
685 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
686 errmsg(rentry->nota_msg, relname),
687 (wentry->kind != '\0') ? errhint("%s", _(wentry->drophint_msg)) : 0));
692 * Implements DROP TABLE, DROP INDEX, DROP SEQUENCE, DROP VIEW,
696 RemoveRelations(DropStmt *drop)
698 ObjectAddresses *objects;
703 * First we identify all the relations, then we delete them in a single
704 * performMultipleDeletions() call. This is to avoid unwanted DROP
705 * RESTRICT errors if one of the relations depends on another.
708 /* Determine required relkind */
709 switch (drop->removeType)
712 relkind = RELKIND_RELATION;
716 relkind = RELKIND_INDEX;
719 case OBJECT_SEQUENCE:
720 relkind = RELKIND_SEQUENCE;
724 relkind = RELKIND_VIEW;
727 case OBJECT_FOREIGN_TABLE:
728 relkind = RELKIND_FOREIGN_TABLE;
732 elog(ERROR, "unrecognized drop object type: %d",
733 (int) drop->removeType);
734 relkind = 0; /* keep compiler quiet */
738 /* Lock and validate each relation; build a list of object addresses */
739 objects = new_object_addresses();
741 foreach(cell, drop->objects)
743 RangeVar *rel = makeRangeVarFromNameList((List *) lfirst(cell));
746 Form_pg_class classform;
750 * These next few steps are a great deal like relation_openrv, but we
751 * don't bother building a relcache entry since we don't need it.
753 * Check for shared-cache-inval messages before trying to access the
754 * relation. This is needed to cover the case where the name
755 * identifies a rel that has been dropped and recreated since the
756 * start of our transaction: if we don't flush the old syscache entry,
757 * then we'll latch onto that entry and suffer an error later.
759 AcceptInvalidationMessages();
761 /* Look up the appropriate relation using namespace search */
762 relOid = RangeVarGetRelid(rel, true);
765 if (!OidIsValid(relOid))
767 DropErrorMsgNonExistent(rel->relname, relkind, drop->missing_ok);
772 * In DROP INDEX, attempt to acquire lock on the parent table before
773 * locking the index. index_drop() will need this anyway, and since
774 * regular queries lock tables before their indexes, we risk deadlock
775 * if we do it the other way around. No error if we don't find a
776 * pg_index entry, though --- that most likely means it isn't an
777 * index, and we'll fail below.
779 if (relkind == RELKIND_INDEX)
781 tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relOid));
782 if (HeapTupleIsValid(tuple))
784 Form_pg_index index = (Form_pg_index) GETSTRUCT(tuple);
786 LockRelationOid(index->indrelid, AccessExclusiveLock);
787 ReleaseSysCache(tuple);
791 /* Get the lock before trying to fetch the syscache entry */
792 LockRelationOid(relOid, AccessExclusiveLock);
794 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
795 if (!HeapTupleIsValid(tuple))
796 elog(ERROR, "cache lookup failed for relation %u", relOid);
797 classform = (Form_pg_class) GETSTRUCT(tuple);
799 if (classform->relkind != relkind)
800 DropErrorMsgWrongType(rel->relname, classform->relkind, relkind);
802 /* Allow DROP to either table owner or schema owner */
803 if (!pg_class_ownercheck(relOid, GetUserId()) &&
804 !pg_namespace_ownercheck(classform->relnamespace, GetUserId()))
805 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
808 if (!allowSystemTableMods && IsSystemClass(classform))
810 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
811 errmsg("permission denied: \"%s\" is a system catalog",
814 /* OK, we're ready to delete this one */
815 obj.classId = RelationRelationId;
816 obj.objectId = relOid;
819 add_exact_object_address(&obj, objects);
821 ReleaseSysCache(tuple);
824 performMultipleDeletions(objects, drop->behavior);
826 free_object_addresses(objects);
831 * Executes a TRUNCATE command.
833 * This is a multi-relation truncate. We first open and grab exclusive
834 * lock on all relations involved, checking permissions and otherwise
835 * verifying that the relation is OK for truncation. In CASCADE mode,
836 * relations having FK references to the targeted relations are automatically
837 * added to the group; in RESTRICT mode, we check that all FK references are
838 * internal to the group that's being truncated. Finally all the relations
839 * are truncated and reindexed.
842 ExecuteTruncate(TruncateStmt *stmt)
846 List *seq_relids = NIL;
848 ResultRelInfo *resultRelInfos;
849 ResultRelInfo *resultRelInfo;
850 SubTransactionId mySubid;
854 * Open, exclusive-lock, and check all the explicitly-specified relations
856 foreach(cell, stmt->relations)
858 RangeVar *rv = lfirst(cell);
860 bool recurse = interpretInhOption(rv->inhOpt);
863 rel = heap_openrv(rv, AccessExclusiveLock);
864 myrelid = RelationGetRelid(rel);
865 /* don't throw error for "TRUNCATE foo, foo" */
866 if (list_member_oid(relids, myrelid))
868 heap_close(rel, AccessExclusiveLock);
871 truncate_check_rel(rel);
872 rels = lappend(rels, rel);
873 relids = lappend_oid(relids, myrelid);
880 children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL);
882 foreach(child, children)
884 Oid childrelid = lfirst_oid(child);
886 if (list_member_oid(relids, childrelid))
889 /* find_all_inheritors already got lock */
890 rel = heap_open(childrelid, NoLock);
891 truncate_check_rel(rel);
892 rels = lappend(rels, rel);
893 relids = lappend_oid(relids, childrelid);
899 * In CASCADE mode, suck in all referencing relations as well. This
900 * requires multiple iterations to find indirectly-dependent relations. At
901 * each phase, we need to exclusive-lock new rels before looking for their
902 * dependencies, else we might miss something. Also, we check each rel as
903 * soon as we open it, to avoid a faux pas such as holding lock for a long
904 * time on a rel we have no permissions for.
906 if (stmt->behavior == DROP_CASCADE)
912 newrelids = heap_truncate_find_FKs(relids);
913 if (newrelids == NIL)
914 break; /* nothing else to add */
916 foreach(cell, newrelids)
918 Oid relid = lfirst_oid(cell);
921 rel = heap_open(relid, AccessExclusiveLock);
923 (errmsg("truncate cascades to table \"%s\"",
924 RelationGetRelationName(rel))));
925 truncate_check_rel(rel);
926 rels = lappend(rels, rel);
927 relids = lappend_oid(relids, relid);
933 * Check foreign key references. In CASCADE mode, this should be
934 * unnecessary since we just pulled in all the references; but as a
935 * cross-check, do it anyway if in an Assert-enabled build.
937 #ifdef USE_ASSERT_CHECKING
938 heap_truncate_check_FKs(rels, false);
940 if (stmt->behavior == DROP_RESTRICT)
941 heap_truncate_check_FKs(rels, false);
945 * If we are asked to restart sequences, find all the sequences, lock them
946 * (we need AccessExclusiveLock for ResetSequence), and check permissions.
947 * We want to do this early since it's pointless to do all the truncation
948 * work only to fail on sequence permissions.
950 if (stmt->restart_seqs)
954 Relation rel = (Relation) lfirst(cell);
955 List *seqlist = getOwnedSequences(RelationGetRelid(rel));
958 foreach(seqcell, seqlist)
960 Oid seq_relid = lfirst_oid(seqcell);
963 seq_rel = relation_open(seq_relid, AccessExclusiveLock);
965 /* This check must match AlterSequence! */
966 if (!pg_class_ownercheck(seq_relid, GetUserId()))
967 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
968 RelationGetRelationName(seq_rel));
970 seq_relids = lappend_oid(seq_relids, seq_relid);
972 relation_close(seq_rel, NoLock);
977 /* Prepare to catch AFTER triggers. */
978 AfterTriggerBeginQuery();
981 * To fire triggers, we'll need an EState as well as a ResultRelInfo for
982 * each relation. We don't need to call ExecOpenIndices, though.
984 estate = CreateExecutorState();
985 resultRelInfos = (ResultRelInfo *)
986 palloc(list_length(rels) * sizeof(ResultRelInfo));
987 resultRelInfo = resultRelInfos;
990 Relation rel = (Relation) lfirst(cell);
992 InitResultRelInfo(resultRelInfo,
994 0, /* dummy rangetable index */
998 estate->es_result_relations = resultRelInfos;
999 estate->es_num_result_relations = list_length(rels);
1002 * Process all BEFORE STATEMENT TRUNCATE triggers before we begin
1003 * truncating (this is because one of them might throw an error). Also, if
1004 * we were to allow them to prevent statement execution, that would need
1005 * to be handled here.
1007 resultRelInfo = resultRelInfos;
1010 estate->es_result_relation_info = resultRelInfo;
1011 ExecBSTruncateTriggers(estate, resultRelInfo);
1016 * OK, truncate each table.
1018 mySubid = GetCurrentSubTransactionId();
1022 Relation rel = (Relation) lfirst(cell);
1025 * Normally, we need a transaction-safe truncation here. However, if
1026 * the table was either created in the current (sub)transaction or has
1027 * a new relfilenode in the current (sub)transaction, then we can just
1028 * truncate it in-place, because a rollback would cause the whole
1029 * table or the current physical file to be thrown away anyway.
1031 if (rel->rd_createSubid == mySubid ||
1032 rel->rd_newRelfilenodeSubid == mySubid)
1034 /* Immediate, non-rollbackable truncation is OK */
1035 heap_truncate_one_rel(rel);
1043 * Need the full transaction-safe pushups.
1045 * Create a new empty storage file for the relation, and assign it
1046 * as the relfilenode value. The old storage file is scheduled for
1047 * deletion at commit.
1049 RelationSetNewRelfilenode(rel, RecentXmin);
1051 heap_relid = RelationGetRelid(rel);
1052 toast_relid = rel->rd_rel->reltoastrelid;
1055 * The same for the toast table, if any.
1057 if (OidIsValid(toast_relid))
1059 rel = relation_open(toast_relid, AccessExclusiveLock);
1060 RelationSetNewRelfilenode(rel, RecentXmin);
1061 heap_close(rel, NoLock);
1065 * Reconstruct the indexes to match, and we're done.
1067 reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST);
1072 * Restart owned sequences if we were asked to.
1074 foreach(cell, seq_relids)
1076 Oid seq_relid = lfirst_oid(cell);
1078 ResetSequence(seq_relid);
1082 * Process all AFTER STATEMENT TRUNCATE triggers.
1084 resultRelInfo = resultRelInfos;
1087 estate->es_result_relation_info = resultRelInfo;
1088 ExecASTruncateTriggers(estate, resultRelInfo);
1092 /* Handle queued AFTER triggers */
1093 AfterTriggerEndQuery(estate);
1095 /* We can clean up the EState now */
1096 FreeExecutorState(estate);
1098 /* And close the rels (can't do this while EState still holds refs) */
1101 Relation rel = (Relation) lfirst(cell);
1103 heap_close(rel, NoLock);
1108 * Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate
1111 truncate_check_rel(Relation rel)
1113 AclResult aclresult;
1115 /* Only allow truncate on regular tables */
1116 if (rel->rd_rel->relkind != RELKIND_RELATION)
1118 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1119 errmsg("\"%s\" is not a table",
1120 RelationGetRelationName(rel))));
1122 /* Permissions checks */
1123 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
1125 if (aclresult != ACLCHECK_OK)
1126 aclcheck_error(aclresult, ACL_KIND_CLASS,
1127 RelationGetRelationName(rel));
1129 if (!allowSystemTableMods && IsSystemRelation(rel))
1131 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1132 errmsg("permission denied: \"%s\" is a system catalog",
1133 RelationGetRelationName(rel))));
1136 * Don't allow truncate on temp tables of other backends ... their local
1137 * buffer manager is not going to cope.
1139 if (RELATION_IS_OTHER_TEMP(rel))
1141 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1142 errmsg("cannot truncate temporary tables of other sessions")));
1145 * Also check for active uses of the relation in the current transaction,
1146 * including open scans and pending AFTER trigger events.
1148 CheckTableNotInUse(rel, "TRUNCATE");
1153 * returns the name corresponding to a typstorage/attstorage enum value
1156 storage_name(char c)
1175 * Returns new schema given initial schema and superclasses.
1178 * 'schema' is the column/attribute definition for the table. (It's a list
1179 * of ColumnDef's.) It is destructively changed.
1180 * 'supers' is a list of names (as RangeVar nodes) of parent relations.
1181 * 'relpersistence' is a persistence type of the table.
1184 * 'supOids' receives a list of the OIDs of the parent relations.
1185 * 'supconstr' receives a list of constraints belonging to the parents,
1186 * updated as necessary to be valid for the child.
1187 * 'supOidCount' is set to the number of parents that have OID columns.
1190 * Completed schema list.
1193 * The order in which the attributes are inherited is very important.
1194 * Intuitively, the inherited attributes should come first. If a table
1195 * inherits from multiple parents, the order of those attributes are
1196 * according to the order of the parents specified in CREATE TABLE.
1198 * Here's an example:
1200 * create table person (name text, age int4, location point);
1201 * create table emp (salary int4, manager text) inherits(person);
1202 * create table student (gpa float8) inherits (person);
1203 * create table stud_emp (percent int4) inherits (emp, student);
1205 * The order of the attributes of stud_emp is:
1207 * person {1:name, 2:age, 3:location}
1209 * {6:gpa} student emp {4:salary, 5:manager}
1211 * stud_emp {7:percent}
1213 * If the same attribute name appears multiple times, then it appears
1214 * in the result table in the proper location for its first appearance.
1216 * Constraints (including NOT NULL constraints) for the child table
1217 * are the union of all relevant constraints, from both the child schema
1218 * and parent tables.
1220 * The default value for a child column is defined as:
1221 * (1) If the child schema specifies a default, that value is used.
1222 * (2) If neither the child nor any parent specifies a default, then
1223 * the column will not have a default.
1224 * (3) If conflicting defaults are inherited from different parents
1225 * (and not overridden by the child), an error is raised.
1226 * (4) Otherwise the inherited default is used.
1227 * Rule (3) is new in Postgres 7.1; in earlier releases you got a
1228 * rather arbitrary choice of which parent default to use.
1232 MergeAttributes(List *schema, List *supers, char relpersistence,
1233 List **supOids, List **supconstr, int *supOidCount)
1236 List *inhSchema = NIL;
1237 List *parentOids = NIL;
1238 List *constraints = NIL;
1239 int parentsWithOids = 0;
1240 bool have_bogus_defaults = false;
1242 static Node bogus_marker = {0}; /* marks conflicting defaults */
1245 * Check for and reject tables with too many columns. We perform this
1246 * check relatively early for two reasons: (a) we don't run the risk of
1247 * overflowing an AttrNumber in subsequent code (b) an O(n^2) algorithm is
1248 * okay if we're processing <= 1600 columns, but could take minutes to
1249 * execute if the user attempts to create a table with hundreds of
1250 * thousands of columns.
1252 * Note that we also need to check that any we do not exceed this figure
1253 * after including columns from inherited relations.
1255 if (list_length(schema) > MaxHeapAttributeNumber)
1257 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1258 errmsg("tables can have at most %d columns",
1259 MaxHeapAttributeNumber)));
1262 * Check for duplicate names in the explicit list of attributes.
1264 * Although we might consider merging such entries in the same way that we
1265 * handle name conflicts for inherited attributes, it seems to make more
1266 * sense to assume such conflicts are errors.
1268 foreach(entry, schema)
1270 ColumnDef *coldef = lfirst(entry);
1271 ListCell *rest = lnext(entry);
1272 ListCell *prev = entry;
1274 if (coldef->typeName == NULL)
1277 * Typed table column option that does not belong to a column from
1278 * the type. This works because the columns from the type come
1279 * first in the list.
1282 (errcode(ERRCODE_UNDEFINED_COLUMN),
1283 errmsg("column \"%s\" does not exist",
1286 while (rest != NULL)
1288 ColumnDef *restdef = lfirst(rest);
1289 ListCell *next = lnext(rest); /* need to save it in case we
1292 if (strcmp(coldef->colname, restdef->colname) == 0)
1294 if (coldef->is_from_type)
1297 * merge the column options into the column from the type
1299 coldef->is_not_null = restdef->is_not_null;
1300 coldef->raw_default = restdef->raw_default;
1301 coldef->cooked_default = restdef->cooked_default;
1302 coldef->constraints = restdef->constraints;
1303 coldef->is_from_type = false;
1304 list_delete_cell(schema, rest, prev);
1308 (errcode(ERRCODE_DUPLICATE_COLUMN),
1309 errmsg("column \"%s\" specified more than once",
1318 * Scan the parents left-to-right, and merge their attributes to form a
1319 * list of inherited attributes (inhSchema). Also check to see if we need
1320 * to inherit an OID column.
1323 foreach(entry, supers)
1325 RangeVar *parent = (RangeVar *) lfirst(entry);
1327 TupleDesc tupleDesc;
1328 TupleConstr *constr;
1329 AttrNumber *newattno;
1330 AttrNumber parent_attno;
1333 * A self-exclusive lock is needed here. If two backends attempt to
1334 * add children to the same parent simultaneously, and that parent has
1335 * no pre-existing children, then both will attempt to update the
1336 * parent's relhassubclass field, leading to a "tuple concurrently
1339 relation = heap_openrv(parent, ShareUpdateExclusiveLock);
1341 if (relation->rd_rel->relkind != RELKIND_RELATION)
1343 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1344 errmsg("inherited relation \"%s\" is not a table",
1346 /* Permanent rels cannot inherit from temporary ones */
1347 if (relpersistence != RELPERSISTENCE_TEMP
1348 && RelationUsesTempNamespace(relation))
1350 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1351 errmsg("cannot inherit from temporary relation \"%s\"",
1355 * We should have an UNDER permission flag for this, but for now,
1356 * demand that creator of a child table own the parent.
1358 if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
1359 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
1360 RelationGetRelationName(relation));
1363 * Reject duplications in the list of parents.
1365 if (list_member_oid(parentOids, RelationGetRelid(relation)))
1367 (errcode(ERRCODE_DUPLICATE_TABLE),
1368 errmsg("relation \"%s\" would be inherited from more than once",
1371 parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
1373 if (relation->rd_rel->relhasoids)
1376 tupleDesc = RelationGetDescr(relation);
1377 constr = tupleDesc->constr;
1380 * newattno[] will contain the child-table attribute numbers for the
1381 * attributes of this parent table. (They are not the same for
1382 * parents after the first one, nor if we have dropped columns.)
1384 newattno = (AttrNumber *)
1385 palloc(tupleDesc->natts * sizeof(AttrNumber));
1387 for (parent_attno = 1; parent_attno <= tupleDesc->natts;
1390 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
1391 char *attributeName = NameStr(attribute->attname);
1396 * Ignore dropped columns in the parent.
1398 if (attribute->attisdropped)
1401 * change_varattnos_of_a_node asserts that this is greater
1402 * than zero, so if anything tries to use it, we should find
1405 newattno[parent_attno - 1] = 0;
1410 * Does it conflict with some previously inherited column?
1412 exist_attno = findAttrByName(attributeName, inhSchema);
1413 if (exist_attno > 0)
1420 * Yes, try to merge the two column definitions. They must
1421 * have the same type, typmod, and collation.
1424 (errmsg("merging multiple inherited definitions of column \"%s\"",
1426 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1427 typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
1428 if (defTypeId != attribute->atttypid ||
1429 deftypmod != attribute->atttypmod)
1431 (errcode(ERRCODE_DATATYPE_MISMATCH),
1432 errmsg("inherited column \"%s\" has a type conflict",
1434 errdetail("%s versus %s",
1435 TypeNameToString(def->typeName),
1436 format_type_be(attribute->atttypid))));
1437 defCollId = GetColumnDefCollation(NULL, def, defTypeId);
1438 if (defCollId != attribute->attcollation)
1440 (errcode(ERRCODE_COLLATION_MISMATCH),
1441 errmsg("inherited column \"%s\" has a collation conflict",
1443 errdetail("\"%s\" versus \"%s\"",
1444 get_collation_name(defCollId),
1445 get_collation_name(attribute->attcollation))));
1447 /* Copy storage parameter */
1448 if (def->storage == 0)
1449 def->storage = attribute->attstorage;
1450 else if (def->storage != attribute->attstorage)
1452 (errcode(ERRCODE_DATATYPE_MISMATCH),
1453 errmsg("inherited column \"%s\" has a storage parameter conflict",
1455 errdetail("%s versus %s",
1456 storage_name(def->storage),
1457 storage_name(attribute->attstorage))));
1460 /* Merge of NOT NULL constraints = OR 'em together */
1461 def->is_not_null |= attribute->attnotnull;
1462 /* Default and other constraints are handled below */
1463 newattno[parent_attno - 1] = exist_attno;
1468 * No, create a new inherited column
1470 def = makeNode(ColumnDef);
1471 def->colname = pstrdup(attributeName);
1472 def->typeName = makeTypeNameFromOid(attribute->atttypid,
1473 attribute->atttypmod);
1475 def->is_local = false;
1476 def->is_not_null = attribute->attnotnull;
1477 def->is_from_type = false;
1478 def->storage = attribute->attstorage;
1479 def->raw_default = NULL;
1480 def->cooked_default = NULL;
1481 def->collClause = NULL;
1482 def->collOid = attribute->attcollation;
1483 def->constraints = NIL;
1484 inhSchema = lappend(inhSchema, def);
1485 newattno[parent_attno - 1] = ++child_attno;
1489 * Copy default if any
1491 if (attribute->atthasdef)
1493 Node *this_default = NULL;
1494 AttrDefault *attrdef;
1497 /* Find default in constraint structure */
1498 Assert(constr != NULL);
1499 attrdef = constr->defval;
1500 for (i = 0; i < constr->num_defval; i++)
1502 if (attrdef[i].adnum == parent_attno)
1504 this_default = stringToNode(attrdef[i].adbin);
1508 Assert(this_default != NULL);
1511 * If default expr could contain any vars, we'd need to fix
1512 * 'em, but it can't; so default is ready to apply to child.
1514 * If we already had a default from some prior parent, check
1515 * to see if they are the same. If so, no problem; if not,
1516 * mark the column as having a bogus default. Below, we will
1517 * complain if the bogus default isn't overridden by the child
1520 Assert(def->raw_default == NULL);
1521 if (def->cooked_default == NULL)
1522 def->cooked_default = this_default;
1523 else if (!equal(def->cooked_default, this_default))
1525 def->cooked_default = &bogus_marker;
1526 have_bogus_defaults = true;
1532 * Now copy the CHECK constraints of this parent, adjusting attnos
1533 * using the completed newattno[] map. Identically named constraints
1534 * are merged if possible, else we throw error.
1536 if (constr && constr->num_check > 0)
1538 ConstrCheck *check = constr->check;
1541 for (i = 0; i < constr->num_check; i++)
1543 char *name = check[i].ccname;
1546 /* adjust varattnos of ccbin here */
1547 expr = stringToNode(check[i].ccbin);
1548 change_varattnos_of_a_node(expr, newattno);
1550 /* check for duplicate */
1551 if (!MergeCheckConstraint(constraints, name, expr))
1553 /* nope, this is a new one */
1554 CookedConstraint *cooked;
1556 cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
1557 cooked->contype = CONSTR_CHECK;
1558 cooked->name = pstrdup(name);
1559 cooked->attnum = 0; /* not used for constraints */
1560 cooked->expr = expr;
1561 cooked->is_local = false;
1562 cooked->inhcount = 1;
1563 constraints = lappend(constraints, cooked);
1571 * Close the parent rel, but keep our AccessShareLock on it until xact
1572 * commit. That will prevent someone else from deleting or ALTERing
1573 * the parent before the child is committed.
1575 heap_close(relation, NoLock);
1579 * If we had no inherited attributes, the result schema is just the
1580 * explicitly declared columns. Otherwise, we need to merge the declared
1581 * columns into the inherited schema list.
1583 if (inhSchema != NIL)
1585 foreach(entry, schema)
1587 ColumnDef *newdef = lfirst(entry);
1588 char *attributeName = newdef->colname;
1592 * Does it conflict with some previously inherited column?
1594 exist_attno = findAttrByName(attributeName, inhSchema);
1595 if (exist_attno > 0)
1606 * Yes, try to merge the two column definitions. They must
1607 * have the same type, typmod, and collation.
1610 (errmsg("merging column \"%s\" with inherited definition",
1612 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1613 typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
1614 typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
1615 if (defTypeId != newTypeId || deftypmod != newtypmod)
1617 (errcode(ERRCODE_DATATYPE_MISMATCH),
1618 errmsg("column \"%s\" has a type conflict",
1620 errdetail("%s versus %s",
1621 TypeNameToString(def->typeName),
1622 TypeNameToString(newdef->typeName))));
1623 defcollid = GetColumnDefCollation(NULL, def, defTypeId);
1624 newcollid = GetColumnDefCollation(NULL, newdef, newTypeId);
1625 if (defcollid != newcollid)
1627 (errcode(ERRCODE_COLLATION_MISMATCH),
1628 errmsg("column \"%s\" has a collation conflict",
1630 errdetail("\"%s\" versus \"%s\"",
1631 get_collation_name(defcollid),
1632 get_collation_name(newcollid))));
1634 /* Copy storage parameter */
1635 if (def->storage == 0)
1636 def->storage = newdef->storage;
1637 else if (newdef->storage != 0 && def->storage != newdef->storage)
1639 (errcode(ERRCODE_DATATYPE_MISMATCH),
1640 errmsg("column \"%s\" has a storage parameter conflict",
1642 errdetail("%s versus %s",
1643 storage_name(def->storage),
1644 storage_name(newdef->storage))));
1646 /* Mark the column as locally defined */
1647 def->is_local = true;
1648 /* Merge of NOT NULL constraints = OR 'em together */
1649 def->is_not_null |= newdef->is_not_null;
1650 /* If new def has a default, override previous default */
1651 if (newdef->raw_default != NULL)
1653 def->raw_default = newdef->raw_default;
1654 def->cooked_default = newdef->cooked_default;
1660 * No, attach new column to result schema
1662 inhSchema = lappend(inhSchema, newdef);
1669 * Check that we haven't exceeded the legal # of columns after merging
1670 * in inherited columns.
1672 if (list_length(schema) > MaxHeapAttributeNumber)
1674 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1675 errmsg("tables can have at most %d columns",
1676 MaxHeapAttributeNumber)));
1680 * If we found any conflicting parent default values, check to make sure
1681 * they were overridden by the child.
1683 if (have_bogus_defaults)
1685 foreach(entry, schema)
1687 ColumnDef *def = lfirst(entry);
1689 if (def->cooked_default == &bogus_marker)
1691 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
1692 errmsg("column \"%s\" inherits conflicting default values",
1694 errhint("To resolve the conflict, specify a default explicitly.")));
1698 *supOids = parentOids;
1699 *supconstr = constraints;
1700 *supOidCount = parentsWithOids;
1706 * MergeCheckConstraint
1707 * Try to merge an inherited CHECK constraint with previous ones
1709 * If we inherit identically-named constraints from multiple parents, we must
1710 * merge them, or throw an error if they don't have identical definitions.
1712 * constraints is a list of CookedConstraint structs for previous constraints.
1714 * Returns TRUE if merged (constraint is a duplicate), or FALSE if it's
1715 * got a so-far-unique name, or throws error if conflict.
1718 MergeCheckConstraint(List *constraints, char *name, Node *expr)
1722 foreach(lc, constraints)
1724 CookedConstraint *ccon = (CookedConstraint *) lfirst(lc);
1726 Assert(ccon->contype == CONSTR_CHECK);
1728 /* Non-matching names never conflict */
1729 if (strcmp(ccon->name, name) != 0)
1732 if (equal(expr, ccon->expr))
1740 (errcode(ERRCODE_DUPLICATE_OBJECT),
1741 errmsg("check constraint name \"%s\" appears multiple times but with different expressions",
1750 * Replace varattno values in an expression tree according to the given
1751 * map array, that is, varattno N is replaced by newattno[N-1]. It is
1752 * caller's responsibility to ensure that the array is long enough to
1753 * define values for all user varattnos present in the tree. System column
1754 * attnos remain unchanged.
1756 * Note that the passed node tree is modified in-place!
1759 change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1761 /* no setup needed, so away we go */
1762 (void) change_varattnos_walker(node, newattno);
1766 change_varattnos_walker(Node *node, const AttrNumber *newattno)
1772 Var *var = (Var *) node;
1774 if (var->varlevelsup == 0 && var->varno == 1 &&
1778 * ??? the following may be a problem when the node is multiply
1779 * referenced though stringToNode() doesn't create such a node
1782 Assert(newattno[var->varattno - 1] > 0);
1783 var->varattno = var->varoattno = newattno[var->varattno - 1];
1787 return expression_tree_walker(node, change_varattnos_walker,
1792 * Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
1793 * matching according to column name.
1796 varattnos_map(TupleDesc olddesc, TupleDesc newdesc)
1802 attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * olddesc->natts);
1803 for (i = 1; i <= olddesc->natts; i++)
1805 if (olddesc->attrs[i - 1]->attisdropped)
1806 continue; /* leave the entry as zero */
1808 for (j = 1; j <= newdesc->natts; j++)
1810 if (strcmp(NameStr(olddesc->attrs[i - 1]->attname),
1811 NameStr(newdesc->attrs[j - 1]->attname)) == 0)
1822 * Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
1826 varattnos_map_schema(TupleDesc old, List *schema)
1831 attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
1832 for (i = 1; i <= old->natts; i++)
1834 if (old->attrs[i - 1]->attisdropped)
1835 continue; /* leave the entry as zero */
1837 attmap[i - 1] = findAttrByName(NameStr(old->attrs[i - 1]->attname),
1845 * StoreCatalogInheritance
1846 * Updates the system catalogs with proper inheritance information.
1848 * supers is a list of the OIDs of the new relation's direct ancestors.
1851 StoreCatalogInheritance(Oid relationId, List *supers)
1860 AssertArg(OidIsValid(relationId));
1866 * Store INHERITS information in pg_inherits using direct ancestors only.
1867 * Also enter dependencies on the direct ancestors, and make sure they are
1868 * marked with relhassubclass = true.
1870 * (Once upon a time, both direct and indirect ancestors were found here
1871 * and then entered into pg_ipl. Since that catalog doesn't exist
1872 * anymore, there's no need to look for indirect ancestors.)
1874 relation = heap_open(InheritsRelationId, RowExclusiveLock);
1877 foreach(entry, supers)
1879 Oid parentOid = lfirst_oid(entry);
1881 StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation);
1885 heap_close(relation, RowExclusiveLock);
1889 * Make catalog entries showing relationId as being an inheritance child
1890 * of parentOid. inhRelation is the already-opened pg_inherits catalog.
1893 StoreCatalogInheritance1(Oid relationId, Oid parentOid,
1894 int16 seqNumber, Relation inhRelation)
1896 TupleDesc desc = RelationGetDescr(inhRelation);
1897 Datum values[Natts_pg_inherits];
1898 bool nulls[Natts_pg_inherits];
1899 ObjectAddress childobject,
1904 * Make the pg_inherits entry
1906 values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(relationId);
1907 values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
1908 values[Anum_pg_inherits_inhseqno - 1] = Int16GetDatum(seqNumber);
1910 memset(nulls, 0, sizeof(nulls));
1912 tuple = heap_form_tuple(desc, values, nulls);
1914 simple_heap_insert(inhRelation, tuple);
1916 CatalogUpdateIndexes(inhRelation, tuple);
1918 heap_freetuple(tuple);
1921 * Store a dependency too
1923 parentobject.classId = RelationRelationId;
1924 parentobject.objectId = parentOid;
1925 parentobject.objectSubId = 0;
1926 childobject.classId = RelationRelationId;
1927 childobject.objectId = relationId;
1928 childobject.objectSubId = 0;
1930 recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
1933 * Mark the parent as having subclasses.
1935 setRelhassubclassInRelation(parentOid, true);
1939 * Look for an existing schema entry with the given name.
1941 * Returns the index (starting with 1) if attribute already exists in schema,
1945 findAttrByName(const char *attributeName, List *schema)
1952 ColumnDef *def = lfirst(s);
1954 if (strcmp(attributeName, def->colname) == 0)
1963 * Update a relation's pg_class.relhassubclass entry to the given value
1966 setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1968 Relation relationRelation;
1970 Form_pg_class classtuple;
1973 * Fetch a modifiable copy of the tuple, modify it, update pg_class.
1975 * If the tuple already has the right relhassubclass setting, we don't
1976 * need to update it, but we still need to issue an SI inval message.
1978 relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
1979 tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
1980 if (!HeapTupleIsValid(tuple))
1981 elog(ERROR, "cache lookup failed for relation %u", relationId);
1982 classtuple = (Form_pg_class) GETSTRUCT(tuple);
1984 if (classtuple->relhassubclass != relhassubclass)
1986 classtuple->relhassubclass = relhassubclass;
1987 simple_heap_update(relationRelation, &tuple->t_self, tuple);
1989 /* keep the catalog indexes up to date */
1990 CatalogUpdateIndexes(relationRelation, tuple);
1994 /* no need to change tuple, but force relcache rebuild anyway */
1995 CacheInvalidateRelcacheByTuple(tuple);
1998 heap_freetuple(tuple);
1999 heap_close(relationRelation, RowExclusiveLock);
2004 * renameatt_internal - workhorse for renameatt
2007 renameatt_internal(Oid myrelid,
2008 const char *oldattname,
2009 const char *newattname,
2012 int expected_parents,
2013 DropBehavior behavior)
2015 Relation targetrelation;
2016 Relation attrelation;
2018 Form_pg_attribute attform;
2023 * Grab an exclusive lock on the target table, which we will NOT release
2024 * until end of transaction.
2026 targetrelation = relation_open(myrelid, AccessExclusiveLock);
2028 if (targetrelation->rd_rel->reloftype && !recursing)
2030 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2031 errmsg("cannot rename column of typed table")));
2034 * Renaming the columns of sequences or toast tables doesn't actually
2035 * break anything from the system's point of view, since internal
2036 * references are by attnum. But it doesn't seem right to allow users to
2037 * change names that are hardcoded into the system, hence the following
2040 relkind = RelationGetForm(targetrelation)->relkind;
2041 if (relkind != RELKIND_RELATION &&
2042 relkind != RELKIND_VIEW &&
2043 relkind != RELKIND_COMPOSITE_TYPE &&
2044 relkind != RELKIND_INDEX &&
2045 relkind != RELKIND_FOREIGN_TABLE)
2047 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2048 errmsg("\"%s\" is not a table, view, composite type, index or foreign table",
2049 RelationGetRelationName(targetrelation))));
2052 * permissions checking. only the owner of a class can change its schema.
2054 if (!pg_class_ownercheck(myrelid, GetUserId()))
2055 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
2056 RelationGetRelationName(targetrelation));
2057 if (!allowSystemTableMods && IsSystemRelation(targetrelation))
2059 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2060 errmsg("permission denied: \"%s\" is a system catalog",
2061 RelationGetRelationName(targetrelation))));
2064 * if the 'recurse' flag is set then we are supposed to rename this
2065 * attribute in all classes that inherit from 'relname' (as well as in
2068 * any permissions or problems with duplicate attributes will cause the
2069 * whole transaction to abort, which is what we want -- all or nothing.
2079 * we need the number of parents for each child so that the recursive
2080 * calls to renameatt() can determine whether there are any parents
2081 * outside the inheritance hierarchy being processed.
2083 child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
2087 * find_all_inheritors does the recursive search of the inheritance
2088 * hierarchy, so all we have to do is process all of the relids in the
2089 * list that it returns.
2091 forboth(lo, child_oids, li, child_numparents)
2093 Oid childrelid = lfirst_oid(lo);
2094 int numparents = lfirst_int(li);
2096 if (childrelid == myrelid)
2098 /* note we need not recurse again */
2099 renameatt_internal(childrelid, oldattname, newattname, false, true, numparents, behavior);
2105 * If we are told not to recurse, there had better not be any child
2106 * tables; else the rename would put them out of step.
2108 * expected_parents will only be 0 if we are not already recursing.
2110 if (expected_parents == 0 &&
2111 find_inheritance_children(myrelid, NoLock) != NIL)
2113 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2114 errmsg("inherited column \"%s\" must be renamed in child tables too",
2118 /* rename attributes in typed tables of composite type */
2119 if (targetrelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
2124 child_oids = find_typed_table_dependencies(targetrelation->rd_rel->reltype,
2125 RelationGetRelationName(targetrelation),
2128 foreach(lo, child_oids)
2129 renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior);
2132 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
2134 atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
2135 if (!HeapTupleIsValid(atttup))
2137 (errcode(ERRCODE_UNDEFINED_COLUMN),
2138 errmsg("column \"%s\" does not exist",
2140 attform = (Form_pg_attribute) GETSTRUCT(atttup);
2142 attnum = attform->attnum;
2145 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2146 errmsg("cannot rename system column \"%s\"",
2150 * if the attribute is inherited, forbid the renaming. if this is a
2151 * top-level call to renameatt(), then expected_parents will be 0, so the
2152 * effect of this code will be to prohibit the renaming if the attribute
2153 * is inherited at all. if this is a recursive call to renameatt(),
2154 * expected_parents will be the number of parents the current relation has
2155 * within the inheritance hierarchy being processed, so we'll prohibit the
2156 * renaming only if there are additional parents from elsewhere.
2158 if (attform->attinhcount > expected_parents)
2160 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2161 errmsg("cannot rename inherited column \"%s\"",
2164 /* new name should not already exist */
2166 /* this test is deliberately not attisdropped-aware */
2167 if (SearchSysCacheExists2(ATTNAME,
2168 ObjectIdGetDatum(myrelid),
2169 PointerGetDatum(newattname)))
2171 (errcode(ERRCODE_DUPLICATE_COLUMN),
2172 errmsg("column \"%s\" of relation \"%s\" already exists",
2173 newattname, RelationGetRelationName(targetrelation))));
2175 /* apply the update */
2176 namestrcpy(&(attform->attname), newattname);
2178 simple_heap_update(attrelation, &atttup->t_self, atttup);
2180 /* keep system catalog indexes current */
2181 CatalogUpdateIndexes(attrelation, atttup);
2183 heap_freetuple(atttup);
2185 heap_close(attrelation, RowExclusiveLock);
2187 relation_close(targetrelation, NoLock); /* close rel but keep lock */
2192 * renameatt - changes the name of a attribute in a relation
2195 renameatt(Oid myrelid, RenameStmt *stmt)
2197 renameatt_internal(myrelid,
2198 stmt->subname, /* old att name */
2199 stmt->newname, /* new att name */
2200 interpretInhOption(stmt->relation->inhOpt), /* recursive? */
2201 false, /* recursing? */
2202 0, /* expected inhcount */
2208 * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/FOREIGN TABLE RENAME
2210 * Caller has already done permissions checks.
2213 RenameRelation(Oid myrelid, const char *newrelname, ObjectType reltype)
2215 Relation targetrelation;
2220 * Grab an exclusive lock on the target table, index, sequence or view,
2221 * which we will NOT release until end of transaction.
2223 targetrelation = relation_open(myrelid, AccessExclusiveLock);
2225 namespaceId = RelationGetNamespace(targetrelation);
2226 relkind = targetrelation->rd_rel->relkind;
2229 * For compatibility with prior releases, we don't complain if ALTER TABLE
2230 * or ALTER INDEX is used to rename some other type of relation. But
2231 * ALTER SEQUENCE/VIEW/FOREIGN TABLE are only to be used with relations of
2234 if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
2236 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2237 errmsg("\"%s\" is not a sequence",
2238 RelationGetRelationName(targetrelation))));
2240 if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW)
2242 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2243 errmsg("\"%s\" is not a view",
2244 RelationGetRelationName(targetrelation))));
2246 if (reltype == OBJECT_FOREIGN_TABLE && relkind != RELKIND_FOREIGN_TABLE)
2248 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2249 errmsg("\"%s\" is not a foreign table",
2250 RelationGetRelationName(targetrelation))));
2253 * Don't allow ALTER TABLE on composite types. We want people to use ALTER
2256 if (relkind == RELKIND_COMPOSITE_TYPE)
2258 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2259 errmsg("\"%s\" is a composite type",
2260 RelationGetRelationName(targetrelation)),
2261 errhint("Use ALTER TYPE instead.")));
2264 RenameRelationInternal(myrelid, newrelname, namespaceId);
2267 * Close rel, but keep exclusive lock!
2269 relation_close(targetrelation, NoLock);
2273 * RenameRelationInternal - change the name of a relation
2275 * XXX - When renaming sequences, we don't bother to modify the
2276 * sequence name that is stored within the sequence itself
2277 * (this would cause problems with MVCC). In the future,
2278 * the sequence name should probably be removed from the
2279 * sequence, AFAIK there's no need for it to be there.
2282 RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
2284 Relation targetrelation;
2285 Relation relrelation; /* for RELATION relation */
2287 Form_pg_class relform;
2290 * Grab an exclusive lock on the target table, index, sequence or view,
2291 * which we will NOT release until end of transaction.
2293 targetrelation = relation_open(myrelid, AccessExclusiveLock);
2296 * Find relation's pg_class tuple, and make sure newrelname isn't in use.
2298 relrelation = heap_open(RelationRelationId, RowExclusiveLock);
2300 reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
2301 if (!HeapTupleIsValid(reltup)) /* shouldn't happen */
2302 elog(ERROR, "cache lookup failed for relation %u", myrelid);
2303 relform = (Form_pg_class) GETSTRUCT(reltup);
2305 if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
2307 (errcode(ERRCODE_DUPLICATE_TABLE),
2308 errmsg("relation \"%s\" already exists",
2312 * Update pg_class tuple with new relname. (Scribbling on reltup is OK
2313 * because it's a copy...)
2315 namestrcpy(&(relform->relname), newrelname);
2317 simple_heap_update(relrelation, &reltup->t_self, reltup);
2319 /* keep the system catalog indexes current */
2320 CatalogUpdateIndexes(relrelation, reltup);
2322 heap_freetuple(reltup);
2323 heap_close(relrelation, RowExclusiveLock);
2326 * Also rename the associated type, if any.
2328 if (OidIsValid(targetrelation->rd_rel->reltype))
2329 RenameTypeInternal(targetrelation->rd_rel->reltype,
2330 newrelname, namespaceId);
2333 * Also rename the associated constraint, if any.
2335 if (targetrelation->rd_rel->relkind == RELKIND_INDEX)
2337 Oid constraintId = get_index_constraint(myrelid);
2339 if (OidIsValid(constraintId))
2340 RenameConstraintById(constraintId, newrelname);
2344 * Close rel, but keep exclusive lock!
2346 relation_close(targetrelation, NoLock);
2350 * Disallow ALTER TABLE (and similar commands) when the current backend has
2351 * any open reference to the target table besides the one just acquired by
2352 * the calling command; this implies there's an open cursor or active plan.
2353 * We need this check because our lock doesn't protect us against stomping
2354 * on our own foot, only other people's feet!
2356 * For ALTER TABLE, the only case known to cause serious trouble is ALTER
2357 * COLUMN TYPE, and some changes are obviously pretty benign, so this could
2358 * possibly be relaxed to only error out for certain types of alterations.
2359 * But the use-case for allowing any of these things is not obvious, so we
2360 * won't work hard at it for now.
2362 * We also reject these commands if there are any pending AFTER trigger events
2363 * for the rel. This is certainly necessary for the rewriting variants of
2364 * ALTER TABLE, because they don't preserve tuple TIDs and so the pending
2365 * events would try to fetch the wrong tuples. It might be overly cautious
2366 * in other cases, but again it seems better to err on the side of paranoia.
2368 * REINDEX calls this with "rel" referencing the index to be rebuilt; here
2369 * we are worried about active indexscans on the index. The trigger-event
2370 * check can be skipped, since we are doing no damage to the parent table.
2372 * The statement name (eg, "ALTER TABLE") is passed for use in error messages.
2375 CheckTableNotInUse(Relation rel, const char *stmt)
2377 int expected_refcnt;
2379 expected_refcnt = rel->rd_isnailed ? 2 : 1;
2380 if (rel->rd_refcnt != expected_refcnt)
2382 (errcode(ERRCODE_OBJECT_IN_USE),
2383 /* translator: first %s is a SQL command, eg ALTER TABLE */
2384 errmsg("cannot %s \"%s\" because "
2385 "it is being used by active queries in this session",
2386 stmt, RelationGetRelationName(rel))));
2388 if (rel->rd_rel->relkind != RELKIND_INDEX &&
2389 AfterTriggerPendingOnRel(RelationGetRelid(rel)))
2391 (errcode(ERRCODE_OBJECT_IN_USE),
2392 /* translator: first %s is a SQL command, eg ALTER TABLE */
2393 errmsg("cannot %s \"%s\" because "
2394 "it has pending trigger events",
2395 stmt, RelationGetRelationName(rel))));
2400 * Execute ALTER TABLE, which can be a list of subcommands
2402 * ALTER TABLE is performed in three phases:
2403 * 1. Examine subcommands and perform pre-transformation checking.
2404 * 2. Update system catalogs.
2405 * 3. Scan table(s) to check new constraints, and optionally recopy
2406 * the data into new table(s).
2407 * Phase 3 is not performed unless one or more of the subcommands requires
2408 * it. The intention of this design is to allow multiple independent
2409 * updates of the table schema to be performed with only one pass over the
2412 * ATPrepCmd performs phase 1. A "work queue" entry is created for
2413 * each table to be affected (there may be multiple affected tables if the
2414 * commands traverse a table inheritance hierarchy). Also we do preliminary
2415 * validation of the subcommands, including parse transformation of those
2416 * expressions that need to be evaluated with respect to the old table
2419 * ATRewriteCatalogs performs phase 2 for each affected table. (Note that
2420 * phases 2 and 3 normally do no explicit recursion, since phase 1 already
2421 * did it --- although some subcommands have to recurse in phase 2 instead.)
2422 * Certain subcommands need to be performed before others to avoid
2423 * unnecessary conflicts; for example, DROP COLUMN should come before
2424 * ADD COLUMN. Therefore phase 1 divides the subcommands into multiple
2425 * lists, one for each logical "pass" of phase 2.
2427 * ATRewriteTables performs phase 3 for those tables that need it.
2429 * Thanks to the magic of MVCC, an error anywhere along the way rolls back
2430 * the whole operation; we don't have to do anything special to clean up.
2432 * We lock the table as the first action, with an appropriate lock level
2433 * for the subcommands requested. Any subcommand that needs to rewrite
2434 * tuples in the table forces the whole command to be executed with
2435 * AccessExclusiveLock. If all subcommands do not require rewrite table
2436 * then we may be able to use lower lock levels. We pass the lock level down
2437 * so that we can apply it recursively to inherited tables. Note that the
2438 * lock level we want as we recurse may well be higher than required for
2439 * that specific subcommand. So we pass down the overall lock requirement,
2440 * rather than reassess it at lower levels.
2443 AlterTable(AlterTableStmt *stmt)
2446 LOCKMODE lockmode = AlterTableGetLockLevel(stmt->cmds);
2449 * Acquire same level of lock as already acquired during parsing.
2451 rel = relation_openrv(stmt->relation, lockmode);
2453 CheckTableNotInUse(rel, "ALTER TABLE");
2455 /* Check relation type against type specified in the ALTER command */
2456 switch (stmt->relkind)
2461 * For mostly-historical reasons, we allow ALTER TABLE to apply to
2462 * almost all relation types.
2464 if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE
2465 || rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2467 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2468 errmsg("\"%s\" is not a table",
2469 RelationGetRelationName(rel))));
2473 if (rel->rd_rel->relkind != RELKIND_INDEX)
2475 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2476 errmsg("\"%s\" is not an index",
2477 RelationGetRelationName(rel))));
2480 case OBJECT_SEQUENCE:
2481 if (rel->rd_rel->relkind != RELKIND_SEQUENCE)
2483 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2484 errmsg("\"%s\" is not a sequence",
2485 RelationGetRelationName(rel))));
2489 if (rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
2491 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2492 errmsg("\"%s\" is not a composite type",
2493 RelationGetRelationName(rel))));
2497 if (rel->rd_rel->relkind != RELKIND_VIEW)
2499 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2500 errmsg("\"%s\" is not a view",
2501 RelationGetRelationName(rel))));
2504 case OBJECT_FOREIGN_TABLE:
2505 if (rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
2507 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2508 errmsg("\"%s\" is not a foreign table",
2509 RelationGetRelationName(rel))));
2513 elog(ERROR, "unrecognized object type: %d", (int) stmt->relkind);
2516 ATController(rel, stmt->cmds, interpretInhOption(stmt->relation->inhOpt),
2521 * AlterTableInternal
2523 * ALTER TABLE with target specified by OID
2525 * We do not reject if the relation is already open, because it's quite
2526 * likely that one or more layers of caller have it open. That means it
2527 * is unsafe to use this entry point for alterations that could break
2528 * existing query plans. On the assumption it's not used for such, we
2529 * don't have to reject pending AFTER triggers, either.
2532 AlterTableInternal(Oid relid, List *cmds, bool recurse)
2535 LOCKMODE lockmode = AlterTableGetLockLevel(cmds);
2537 rel = relation_open(relid, lockmode);
2539 ATController(rel, cmds, recurse, lockmode);
2543 * AlterTableGetLockLevel
2545 * Sets the overall lock level required for the supplied list of subcommands.
2546 * Policy for doing this set according to needs of AlterTable(), see
2547 * comments there for overall explanation.
2549 * Function is called before and after parsing, so it must give same
2550 * answer each time it is called. Some subcommands are transformed
2551 * into other subcommand types, so the transform must never be made to a
2552 * lower lock level than previously assigned. All transforms are noted below.
2554 * Since this is called before we lock the table we cannot use table metadata
2555 * to influence the type of lock we acquire.
2557 * There should be no lockmodes hardcoded into the subcommand functions. All
2558 * lockmode decisions for ALTER TABLE are made here only. The one exception is
2559 * ALTER TABLE RENAME which is treated as a different statement type T_RenameStmt
2560 * and does not travel through this section of code and cannot be combined with
2561 * any of the subcommands given here.
2564 AlterTableGetLockLevel(List *cmds)
2567 LOCKMODE lockmode = ShareUpdateExclusiveLock;
2571 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
2572 LOCKMODE cmd_lockmode = AccessExclusiveLock; /* default for compiler */
2574 switch (cmd->subtype)
2577 * Need AccessExclusiveLock for these subcommands because they
2578 * affect or potentially affect both read and write
2581 * New subcommand types should be added here by default.
2583 case AT_AddColumn: /* may rewrite heap, in some cases and visible
2585 case AT_DropColumn: /* change visible to SELECT */
2586 case AT_AddColumnToView: /* CREATE VIEW */
2587 case AT_AlterColumnType: /* must rewrite heap */
2588 case AT_DropConstraint: /* as DROP INDEX */
2589 case AT_AddOids: /* must rewrite heap */
2590 case AT_DropOids: /* calls AT_DropColumn */
2591 case AT_EnableAlwaysRule: /* may change SELECT rules */
2592 case AT_EnableReplicaRule: /* may change SELECT rules */
2593 case AT_EnableRule: /* may change SELECT rules */
2594 case AT_DisableRule: /* may change SELECT rules */
2595 case AT_ChangeOwner: /* change visible to SELECT */
2596 case AT_SetTableSpace: /* must rewrite heap */
2597 case AT_DropNotNull: /* may change some SQL plans */
2599 case AT_GenericOptions:
2600 cmd_lockmode = AccessExclusiveLock;
2604 * These subcommands affect write operations only.
2606 case AT_ColumnDefault:
2607 case AT_ProcessedConstraint: /* becomes AT_AddConstraint */
2608 case AT_AddConstraintRecurse: /* becomes AT_AddConstraint */
2610 case AT_EnableAlwaysTrig:
2611 case AT_EnableReplicaTrig:
2612 case AT_EnableTrigAll:
2613 case AT_EnableTrigUser:
2614 case AT_DisableTrig:
2615 case AT_DisableTrigAll:
2616 case AT_DisableTrigUser:
2617 case AT_AddIndex: /* from ADD CONSTRAINT */
2618 case AT_AddIndexConstraint:
2619 cmd_lockmode = ShareRowExclusiveLock;
2622 case AT_AddConstraint:
2623 if (IsA(cmd->def, Constraint))
2625 Constraint *con = (Constraint *) cmd->def;
2627 switch (con->contype)
2629 case CONSTR_EXCLUSION:
2630 case CONSTR_PRIMARY:
2634 * Cases essentially the same as CREATE INDEX. We
2635 * could reduce the lock strength to ShareLock if
2636 * we can work out how to allow concurrent catalog
2639 cmd_lockmode = ShareRowExclusiveLock;
2641 case CONSTR_FOREIGN:
2644 * We add triggers to both tables when we add a
2645 * Foreign Key, so the lock level must be at least
2646 * as strong as CREATE TRIGGER.
2648 cmd_lockmode = ShareRowExclusiveLock;
2652 cmd_lockmode = ShareRowExclusiveLock;
2658 * These subcommands affect inheritance behaviour. Queries
2659 * started before us will continue to see the old inheritance
2660 * behaviour, while queries started after we commit will see
2661 * new behaviour. No need to prevent reads or writes to the
2662 * subtable while we hook it up though.
2665 case AT_DropInherit:
2666 cmd_lockmode = ShareUpdateExclusiveLock;
2670 * These subcommands affect implicit row type conversion. They
2671 * have affects similar to CREATE/DROP CAST on queries. We
2672 * don't provide for invalidating parse trees as a result of
2673 * such changes. Do avoid concurrent pg_class updates, though.
2677 cmd_lockmode = ShareUpdateExclusiveLock;
2680 * These subcommands affect general strategies for performance
2681 * and maintenance, though don't change the semantic results
2682 * from normal data reads and writes. Delaying an ALTER TABLE
2683 * behind currently active writes only delays the point where
2684 * the new strategy begins to take effect, so there is no
2685 * benefit in waiting. In this case the minimum restriction
2686 * applies: we don't currently allow concurrent catalog
2689 case AT_SetStatistics:
2691 case AT_DropCluster:
2692 case AT_SetRelOptions:
2693 case AT_ResetRelOptions:
2695 case AT_ResetOptions:
2697 case AT_ValidateConstraint:
2698 cmd_lockmode = ShareUpdateExclusiveLock;
2702 elog(ERROR, "unrecognized alter table type: %d",
2703 (int) cmd->subtype);
2708 * Take the greatest lockmode from any subcommand
2710 if (cmd_lockmode > lockmode)
2711 lockmode = cmd_lockmode;
2718 ATController(Relation rel, List *cmds, bool recurse, LOCKMODE lockmode)
2723 /* Phase 1: preliminary examination of commands, create work queue */
2726 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
2728 ATPrepCmd(&wqueue, rel, cmd, recurse, false, lockmode);
2731 /* Close the relation, but keep lock until commit */
2732 relation_close(rel, NoLock);
2734 /* Phase 2: update system catalogs */
2735 ATRewriteCatalogs(&wqueue, lockmode);
2737 /* Phase 3: scan/rewrite tables as needed */
2738 ATRewriteTables(&wqueue, lockmode);
2744 * Traffic cop for ALTER TABLE Phase 1 operations, including simple
2745 * recursion and permission checks.
2747 * Caller must have acquired appropriate lock type on relation already.
2748 * This lock should be held until commit.
2751 ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
2752 bool recurse, bool recursing, LOCKMODE lockmode)
2754 AlteredTableInfo *tab;
2757 /* Find or create work queue entry for this table */
2758 tab = ATGetQueueEntry(wqueue, rel);
2761 * Copy the original subcommand for each table. This avoids conflicts
2762 * when different child tables need to make different parse
2763 * transformations (for example, the same column may have different column
2764 * numbers in different children).
2766 cmd = copyObject(cmd);
2769 * Do permissions checking, recursion to child tables if needed, and any
2770 * additional phase-1 processing needed.
2772 switch (cmd->subtype)
2774 case AT_AddColumn: /* ADD COLUMN */
2775 ATSimplePermissions(rel,
2776 ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2777 ATPrepAddColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2778 /* Recursion occurs during execution phase */
2779 pass = AT_PASS_ADD_COL;
2781 case AT_AddColumnToView: /* add column via CREATE OR REPLACE
2783 ATSimplePermissions(rel, ATT_VIEW);
2784 ATPrepAddColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2785 /* Recursion occurs during execution phase */
2786 pass = AT_PASS_ADD_COL;
2788 case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
2791 * We allow defaults on views so that INSERT into a view can have
2792 * default-ish behavior. This works because the rewriter
2793 * substitutes default values into INSERTs before it expands
2796 ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW);
2797 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2798 /* No command-specific prep needed */
2799 pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
2801 case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
2802 ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
2803 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2804 /* No command-specific prep needed */
2805 pass = AT_PASS_DROP;
2807 case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
2808 ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
2809 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2810 /* No command-specific prep needed */
2811 pass = AT_PASS_ADD_CONSTR;
2813 case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
2814 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2815 /* Performs own permission checks */
2816 ATPrepSetStatistics(rel, cmd->name, cmd->def, lockmode);
2817 pass = AT_PASS_MISC;
2819 case AT_SetOptions: /* ALTER COLUMN SET ( options ) */
2820 case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */
2821 ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2822 /* This command never recurses */
2823 pass = AT_PASS_MISC;
2825 case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
2826 ATSimplePermissions(rel, ATT_TABLE);
2827 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2828 /* No command-specific prep needed */
2829 pass = AT_PASS_MISC;
2831 case AT_DropColumn: /* DROP COLUMN */
2832 ATSimplePermissions(rel,
2833 ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2834 ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2835 /* Recursion occurs during execution phase */
2836 pass = AT_PASS_DROP;
2838 case AT_AddIndex: /* ADD INDEX */
2839 ATSimplePermissions(rel, ATT_TABLE);
2840 /* This command never recurses */
2841 /* No command-specific prep needed */
2842 pass = AT_PASS_ADD_INDEX;
2844 case AT_AddConstraint: /* ADD CONSTRAINT */
2845 ATSimplePermissions(rel, ATT_TABLE);
2846 /* Recursion occurs during execution phase */
2847 /* No command-specific prep needed except saving recurse flag */
2849 cmd->subtype = AT_AddConstraintRecurse;
2850 pass = AT_PASS_ADD_CONSTR;
2852 case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
2853 ATSimplePermissions(rel, ATT_TABLE);
2854 /* This command never recurses */
2855 /* No command-specific prep needed */
2856 pass = AT_PASS_ADD_CONSTR;
2858 case AT_DropConstraint: /* DROP CONSTRAINT */
2859 ATSimplePermissions(rel, ATT_TABLE);
2860 /* Recursion occurs during execution phase */
2861 /* No command-specific prep needed except saving recurse flag */
2863 cmd->subtype = AT_DropConstraintRecurse;
2864 pass = AT_PASS_DROP;
2866 case AT_AlterColumnType: /* ALTER COLUMN TYPE */
2867 ATSimplePermissions(rel,
2868 ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2869 /* Performs own recursion */
2870 ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd, lockmode);
2871 pass = AT_PASS_ALTER_TYPE;
2873 case AT_ChangeOwner: /* ALTER OWNER */
2874 /* This command never recurses */
2875 /* No command-specific prep needed */
2876 pass = AT_PASS_MISC;
2878 case AT_ClusterOn: /* CLUSTER ON */
2879 case AT_DropCluster: /* SET WITHOUT CLUSTER */
2880 ATSimplePermissions(rel, ATT_TABLE);
2881 /* These commands never recurse */
2882 /* No command-specific prep needed */
2883 pass = AT_PASS_MISC;
2885 case AT_AddOids: /* SET WITH OIDS */
2886 ATSimplePermissions(rel, ATT_TABLE);
2887 if (!rel->rd_rel->relhasoids || recursing)
2888 ATPrepAddOids(wqueue, rel, recurse, cmd, lockmode);
2889 /* Recursion occurs during execution phase */
2890 pass = AT_PASS_ADD_COL;
2892 case AT_DropOids: /* SET WITHOUT OIDS */
2893 ATSimplePermissions(rel, ATT_TABLE);
2894 /* Performs own recursion */
2895 if (rel->rd_rel->relhasoids)
2897 AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
2899 dropCmd->subtype = AT_DropColumn;
2900 dropCmd->name = pstrdup("oid");
2901 dropCmd->behavior = cmd->behavior;
2902 ATPrepCmd(wqueue, rel, dropCmd, recurse, false, lockmode);
2904 pass = AT_PASS_DROP;
2906 case AT_SetTableSpace: /* SET TABLESPACE */
2907 ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2908 /* This command never recurses */
2909 ATPrepSetTableSpace(tab, rel, cmd->name, lockmode);
2910 pass = AT_PASS_MISC; /* doesn't actually matter */
2912 case AT_SetRelOptions: /* SET (...) */
2913 case AT_ResetRelOptions: /* RESET (...) */
2914 ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2915 /* This command never recurses */
2916 /* No command-specific prep needed */
2917 pass = AT_PASS_MISC;
2919 case AT_AddInherit: /* INHERIT */
2920 ATSimplePermissions(rel, ATT_TABLE);
2921 /* This command never recurses */
2922 ATPrepAddInherit(rel);
2923 pass = AT_PASS_MISC;
2925 case AT_ValidateConstraint:
2926 case AT_EnableTrig: /* ENABLE TRIGGER variants */
2927 case AT_EnableAlwaysTrig:
2928 case AT_EnableReplicaTrig:
2929 case AT_EnableTrigAll:
2930 case AT_EnableTrigUser:
2931 case AT_DisableTrig: /* DISABLE TRIGGER variants */
2932 case AT_DisableTrigAll:
2933 case AT_DisableTrigUser:
2934 case AT_EnableRule: /* ENABLE/DISABLE RULE variants */
2935 case AT_EnableAlwaysRule:
2936 case AT_EnableReplicaRule:
2937 case AT_DisableRule:
2938 case AT_DropInherit: /* NO INHERIT */
2939 case AT_AddOf: /* OF */
2940 case AT_DropOf: /* NOT OF */
2941 ATSimplePermissions(rel, ATT_TABLE);
2942 /* These commands never recurse */
2943 /* No command-specific prep needed */
2944 pass = AT_PASS_MISC;
2946 case AT_GenericOptions:
2947 ATSimplePermissions(rel, ATT_FOREIGN_TABLE);
2948 /* No command-specific prep needed */
2949 pass = AT_PASS_MISC;
2952 elog(ERROR, "unrecognized alter table type: %d",
2953 (int) cmd->subtype);
2954 pass = 0; /* keep compiler quiet */
2958 /* Add the subcommand to the appropriate list for phase 2 */
2959 tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
2965 * Traffic cop for ALTER TABLE Phase 2 operations. Subcommands are
2966 * dispatched in a "safe" execution order (designed to avoid unnecessary
2970 ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode)
2976 * We process all the tables "in parallel", one pass at a time. This is
2977 * needed because we may have to propagate work from one table to another
2978 * (specifically, ALTER TYPE on a foreign key's PK has to dispatch the
2979 * re-adding of the foreign key constraint to the other table). Work can
2980 * only be propagated into later passes, however.
2982 for (pass = 0; pass < AT_NUM_PASSES; pass++)
2984 /* Go through each table that needs to be processed */
2985 foreach(ltab, *wqueue)
2987 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2988 List *subcmds = tab->subcmds[pass];
2996 * Appropriate lock was obtained by phase 1, needn't get it again
2998 rel = relation_open(tab->relid, NoLock);
3000 foreach(lcmd, subcmds)
3001 ATExecCmd(wqueue, tab, rel, (AlterTableCmd *) lfirst(lcmd), lockmode);
3004 * After the ALTER TYPE pass, do cleanup work (this is not done in
3005 * ATExecAlterColumnType since it should be done only once if
3006 * multiple columns of a table are altered).
3008 if (pass == AT_PASS_ALTER_TYPE)
3009 ATPostAlterTypeCleanup(wqueue, tab, lockmode);
3011 relation_close(rel, NoLock);
3015 /* Check to see if a toast table must be added. */
3016 foreach(ltab, *wqueue)
3018 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3020 if (tab->relkind == RELKIND_RELATION)
3021 AlterTableCreateToastTable(tab->relid, (Datum) 0);
3026 * ATExecCmd: dispatch a subcommand to appropriate execution routine
3029 ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
3030 AlterTableCmd *cmd, LOCKMODE lockmode)
3032 switch (cmd->subtype)
3034 case AT_AddColumn: /* ADD COLUMN */
3035 case AT_AddColumnToView: /* add column via CREATE OR REPLACE
3037 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3038 false, false, false, lockmode);
3040 case AT_AddColumnRecurse:
3041 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3042 false, true, false, lockmode);
3044 case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
3045 ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode);
3047 case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
3048 ATExecDropNotNull(rel, cmd->name, lockmode);
3050 case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
3051 ATExecSetNotNull(tab, rel, cmd->name, lockmode);
3053 case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
3054 ATExecSetStatistics(rel, cmd->name, cmd->def, lockmode);
3056 case AT_SetOptions: /* ALTER COLUMN SET ( options ) */
3057 ATExecSetOptions(rel, cmd->name, cmd->def, false, lockmode);
3059 case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */
3060 ATExecSetOptions(rel, cmd->name, cmd->def, true, lockmode);
3062 case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
3063 ATExecSetStorage(rel, cmd->name, cmd->def, lockmode);
3065 case AT_DropColumn: /* DROP COLUMN */
3066 ATExecDropColumn(wqueue, rel, cmd->name,
3067 cmd->behavior, false, false, cmd->missing_ok, lockmode);
3069 case AT_DropColumnRecurse: /* DROP COLUMN with recursion */
3070 ATExecDropColumn(wqueue, rel, cmd->name,
3071 cmd->behavior, true, false, cmd->missing_ok, lockmode);
3073 case AT_AddIndex: /* ADD INDEX */
3074 ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false, lockmode);
3076 case AT_ReAddIndex: /* ADD INDEX */
3077 ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true, lockmode);
3079 case AT_AddConstraint: /* ADD CONSTRAINT */
3080 ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3083 case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */
3084 ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3087 case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
3088 ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode);
3090 case AT_ValidateConstraint:
3091 ATExecValidateConstraint(rel, cmd->name);
3093 case AT_DropConstraint: /* DROP CONSTRAINT */
3094 ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3096 cmd->missing_ok, lockmode);
3098 case AT_DropConstraintRecurse: /* DROP CONSTRAINT with recursion */
3099 ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3101 cmd->missing_ok, lockmode);
3103 case AT_AlterColumnType: /* ALTER COLUMN TYPE */
3104 ATExecAlterColumnType(tab, rel, cmd, lockmode);
3106 case AT_ChangeOwner: /* ALTER OWNER */
3107 ATExecChangeOwner(RelationGetRelid(rel),
3108 get_role_oid(cmd->name, false),
3111 case AT_ClusterOn: /* CLUSTER ON */
3112 ATExecClusterOn(rel, cmd->name, lockmode);
3114 case AT_DropCluster: /* SET WITHOUT CLUSTER */
3115 ATExecDropCluster(rel, lockmode);
3117 case AT_AddOids: /* SET WITH OIDS */
3118 /* Use the ADD COLUMN code, unless prep decided to do nothing */
3119 if (cmd->def != NULL)
3120 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3121 true, false, false, lockmode);
3123 case AT_AddOidsRecurse: /* SET WITH OIDS */
3124 /* Use the ADD COLUMN code, unless prep decided to do nothing */
3125 if (cmd->def != NULL)
3126 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3127 true, true, false, lockmode);
3129 case AT_DropOids: /* SET WITHOUT OIDS */
3132 * Nothing to do here; we'll have generated a DropColumn
3133 * subcommand to do the real work
3136 case AT_SetTableSpace: /* SET TABLESPACE */
3139 * Nothing to do here; Phase 3 does the work
3142 case AT_SetRelOptions: /* SET (...) */
3143 ATExecSetRelOptions(rel, (List *) cmd->def, false, lockmode);
3145 case AT_ResetRelOptions: /* RESET (...) */
3146 ATExecSetRelOptions(rel, (List *) cmd->def, true, lockmode);
3149 case AT_EnableTrig: /* ENABLE TRIGGER name */
3150 ATExecEnableDisableTrigger(rel, cmd->name,
3151 TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
3153 case AT_EnableAlwaysTrig: /* ENABLE ALWAYS TRIGGER name */
3154 ATExecEnableDisableTrigger(rel, cmd->name,
3155 TRIGGER_FIRES_ALWAYS, false, lockmode);
3157 case AT_EnableReplicaTrig: /* ENABLE REPLICA TRIGGER name */
3158 ATExecEnableDisableTrigger(rel, cmd->name,
3159 TRIGGER_FIRES_ON_REPLICA, false, lockmode);
3161 case AT_DisableTrig: /* DISABLE TRIGGER name */
3162 ATExecEnableDisableTrigger(rel, cmd->name,
3163 TRIGGER_DISABLED, false, lockmode);
3165 case AT_EnableTrigAll: /* ENABLE TRIGGER ALL */
3166 ATExecEnableDisableTrigger(rel, NULL,
3167 TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
3169 case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
3170 ATExecEnableDisableTrigger(rel, NULL,
3171 TRIGGER_DISABLED, false, lockmode);
3173 case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
3174 ATExecEnableDisableTrigger(rel, NULL,
3175 TRIGGER_FIRES_ON_ORIGIN, true, lockmode);
3177 case AT_DisableTrigUser: /* DISABLE TRIGGER USER */
3178 ATExecEnableDisableTrigger(rel, NULL,
3179 TRIGGER_DISABLED, true, lockmode);
3182 case AT_EnableRule: /* ENABLE RULE name */
3183 ATExecEnableDisableRule(rel, cmd->name,
3184 RULE_FIRES_ON_ORIGIN, lockmode);
3186 case AT_EnableAlwaysRule: /* ENABLE ALWAYS RULE name */
3187 ATExecEnableDisableRule(rel, cmd->name,
3188 RULE_FIRES_ALWAYS, lockmode);
3190 case AT_EnableReplicaRule: /* ENABLE REPLICA RULE name */
3191 ATExecEnableDisableRule(rel, cmd->name,
3192 RULE_FIRES_ON_REPLICA, lockmode);
3194 case AT_DisableRule: /* DISABLE RULE name */
3195 ATExecEnableDisableRule(rel, cmd->name,
3196 RULE_DISABLED, lockmode);
3200 ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode);
3202 case AT_DropInherit:
3203 ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode);
3206 ATExecAddOf(rel, (TypeName *) cmd->def, lockmode);
3209 ATExecDropOf(rel, lockmode);
3211 case AT_GenericOptions:
3212 ATExecGenericOptions(rel, (List *) cmd->def);
3215 elog(ERROR, "unrecognized alter table type: %d",
3216 (int) cmd->subtype);
3221 * Bump the command counter to ensure the next subcommand in the sequence
3222 * can see the changes so far
3224 CommandCounterIncrement();
3228 * ATRewriteTables: ALTER TABLE phase 3
3231 ATRewriteTables(List **wqueue, LOCKMODE lockmode)
3235 /* Go through each table that needs to be checked or rewritten */
3236 foreach(ltab, *wqueue)
3238 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3240 /* Foreign tables have no storage. */
3241 if (tab->relkind == RELKIND_FOREIGN_TABLE)
3245 * If we change column data types or add/remove OIDs, the operation
3246 * has to be propagated to tables that use this table's rowtype as a
3247 * column type. tab->newvals will also be non-NULL in the case where
3248 * we're adding a column with a default. We choose to forbid that
3249 * case as well, since composite types might eventually support
3252 * (Eventually we'll probably need to check for composite type
3253 * dependencies even when we're just scanning the table without a
3254 * rewrite, but at the moment a composite type does not enforce any
3255 * constraints, so it's not necessary/appropriate to enforce them just
3258 if (tab->newvals != NIL || tab->rewrite)
3262 rel = heap_open(tab->relid, NoLock);
3263 find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
3264 heap_close(rel, NoLock);
3268 * We only need to rewrite the table if at least one column needs to
3269 * be recomputed, or we are adding/removing the OID column.
3273 /* Build a temporary relation and copy data */
3278 OldHeap = heap_open(tab->relid, NoLock);
3281 * We don't support rewriting of system catalogs; there are too
3282 * many corner cases and too little benefit. In particular this
3283 * is certainly not going to work for mapped catalogs.
3285 if (IsSystemRelation(OldHeap))
3287 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3288 errmsg("cannot rewrite system relation \"%s\"",
3289 RelationGetRelationName(OldHeap))));
3292 * Don't allow rewrite on temp tables of other backends ... their
3293 * local buffer manager is not going to cope.
3295 if (RELATION_IS_OTHER_TEMP(OldHeap))
3297 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3298 errmsg("cannot rewrite temporary tables of other sessions")));
3301 * Select destination tablespace (same as original unless user
3302 * requested a change)
3304 if (tab->newTableSpace)
3305 NewTableSpace = tab->newTableSpace;
3307 NewTableSpace = OldHeap->rd_rel->reltablespace;
3309 heap_close(OldHeap, NoLock);
3311 /* Create transient table that will receive the modified data */
3312 OIDNewHeap = make_new_heap(tab->relid, NewTableSpace);
3315 * Copy the heap data into the new table with the desired
3316 * modifications, and test the current data within the table
3317 * against new constraints generated by ALTER TABLE commands.
3319 ATRewriteTable(tab, OIDNewHeap, lockmode);
3322 * Swap the physical files of the old and new heaps, then rebuild
3323 * indexes and discard the old heap. We can use RecentXmin for
3324 * the table's new relfrozenxid because we rewrote all the tuples
3325 * in ATRewriteTable, so no older Xid remains in the table. Also,
3326 * we never try to swap toast tables by content, since we have no
3327 * interest in letting this code work on system catalogs.
3329 finish_heap_swap(tab->relid, OIDNewHeap,
3330 false, false, true, RecentXmin);
3335 * Test the current data within the table against new constraints
3336 * generated by ALTER TABLE commands, but don't rebuild data.
3338 if (tab->constraints != NIL || tab->new_notnull)
3339 ATRewriteTable(tab, InvalidOid, lockmode);
3342 * If we had SET TABLESPACE but no reason to reconstruct tuples,
3343 * just do a block-by-block copy.
3345 if (tab->newTableSpace)
3346 ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
3351 * Foreign key constraints are checked in a final pass, since (a) it's
3352 * generally best to examine each one separately, and (b) it's at least
3353 * theoretically possible that we have changed both relations of the
3354 * foreign key, and we'd better have finished both rewrites before we try
3355 * to read the tables.
3357 foreach(ltab, *wqueue)
3359 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3360 Relation rel = NULL;
3363 foreach(lcon, tab->constraints)
3365 NewConstraint *con = lfirst(lcon);
3367 if (con->contype == CONSTR_FOREIGN)
3369 Constraint *fkconstraint = (Constraint *) con->qual;
3373 /* Long since locked, no need for another */
3374 rel = heap_open(tab->relid, NoLock);
3377 * We're adding a trigger to both tables, so the lock level
3378 * here should sensibly reflect that.
3380 refrel = heap_open(con->refrelid, ShareRowExclusiveLock);
3382 validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
3387 * No need to mark the constraint row as validated, we did
3388 * that when we inserted the row earlier.
3391 heap_close(refrel, NoLock);
3396 heap_close(rel, NoLock);
3401 * ATRewriteTable: scan or rewrite one table
3403 * OIDNewHeap is InvalidOid if we don't need to rewrite
3406 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
3410 TupleDesc oldTupDesc;
3411 TupleDesc newTupDesc;
3412 bool needscan = false;
3413 List *notnull_attrs;
3418 BulkInsertState bistate;
3422 * Open the relation(s). We have surely already locked the existing
3425 oldrel = heap_open(tab->relid, NoLock);
3426 oldTupDesc = tab->oldDesc;
3427 newTupDesc = RelationGetDescr(oldrel); /* includes all mods */
3429 if (OidIsValid(OIDNewHeap))
3430 newrel = heap_open(OIDNewHeap, lockmode);
3435 * Prepare a BulkInsertState and options for heap_insert. Because we're
3436 * building a new heap, we can skip WAL-logging and fsync it to disk at
3437 * the end instead (unless WAL-logging is required for archiving or
3438 * streaming replication). The FSM is empty too, so don't bother using it.
3442 mycid = GetCurrentCommandId(true);
3443 bistate = GetBulkInsertState();
3445 hi_options = HEAP_INSERT_SKIP_FSM;
3446 if (!XLogIsNeeded())
3447 hi_options |= HEAP_INSERT_SKIP_WAL;
3451 /* keep compiler quiet about using these uninitialized */
3458 * Generate the constraint and default execution states
3461 estate = CreateExecutorState();
3463 /* Build the needed expression execution states */
3464 foreach(l, tab->constraints)
3466 NewConstraint *con = lfirst(l);
3468 switch (con->contype)
3472 con->qualstate = (List *)
3473 ExecPrepareExpr((Expr *) con->qual, estate);
3475 case CONSTR_FOREIGN:
3476 /* Nothing to do here */
3479 elog(ERROR, "unrecognized constraint type: %d",
3480 (int) con->contype);
3484 foreach(l, tab->newvals)
3486 NewColumnValue *ex = lfirst(l);
3488 ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
3491 notnull_attrs = NIL;
3492 if (newrel || tab->new_notnull)
3495 * If we are rebuilding the tuples OR if we added any new NOT NULL
3496 * constraints, check all not-null constraints. This is a bit of
3497 * overkill but it minimizes risk of bugs, and heap_attisnull is a
3498 * pretty cheap test anyway.
3500 for (i = 0; i < newTupDesc->natts; i++)
3502 if (newTupDesc->attrs[i]->attnotnull &&
3503 !newTupDesc->attrs[i]->attisdropped)
3504 notnull_attrs = lappend_int(notnull_attrs, i);
3510 if (newrel || needscan)
3512 ExprContext *econtext;
3515 TupleTableSlot *oldslot;
3516 TupleTableSlot *newslot;
3519 MemoryContext oldCxt;
3520 List *dropped_attrs = NIL;
3525 (errmsg("rewriting table \"%s\"",
3526 RelationGetRelationName(oldrel))));
3529 (errmsg("verifying table \"%s\"",
3530 RelationGetRelationName(oldrel))));
3532 econtext = GetPerTupleExprContext(estate);
3535 * Make tuple slots for old and new tuples. Note that even when the
3536 * tuples are the same, the tupDescs might not be (consider ADD COLUMN
3537 * without a default).
3539 oldslot = MakeSingleTupleTableSlot(oldTupDesc);
3540 newslot = MakeSingleTupleTableSlot(newTupDesc);
3542 /* Preallocate values/isnull arrays */
3543 i = Max(newTupDesc->natts, oldTupDesc->natts);
3544 values = (Datum *) palloc(i * sizeof(Datum));
3545 isnull = (bool *) palloc(i * sizeof(bool));
3546 memset(values, 0, i * sizeof(Datum));
3547 memset(isnull, true, i * sizeof(bool));
3550 * Any attributes that are dropped according to the new tuple
3551 * descriptor can be set to NULL. We precompute the list of dropped
3552 * attributes to avoid needing to do so in the per-tuple loop.
3554 for (i = 0; i < newTupDesc->natts; i++)
3556 if (newTupDesc->attrs[i]->attisdropped)
3557 dropped_attrs = lappend_int(dropped_attrs, i);
3561 * Scan through the rows, generating a new row if needed and then
3562 * checking all the constraints.
3564 scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
3567 * Switch to per-tuple memory context and reset it for each tuple
3568 * produced, so we don't leak memory.
3570 oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
3572 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
3576 Oid tupOid = InvalidOid;
3578 /* Extract data from old tuple */
3579 heap_deform_tuple(tuple, oldTupDesc, values, isnull);
3580 if (oldTupDesc->tdhasoid)
3581 tupOid = HeapTupleGetOid(tuple);
3583 /* Set dropped attributes to null in new tuple */
3584 foreach(lc, dropped_attrs)
3585 isnull[lfirst_int(lc)] = true;
3588 * Process supplied expressions to replace selected columns.
3589 * Expression inputs come from the old tuple.
3591 ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
3592 econtext->ecxt_scantuple = oldslot;
3594 foreach(l, tab->newvals)
3596 NewColumnValue *ex = lfirst(l);
3598 values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
3600 &isnull[ex->attnum - 1],
3605 * Form the new tuple. Note that we don't explicitly pfree it,
3606 * since the per-tuple memory context will be reset shortly.
3608 tuple = heap_form_tuple(newTupDesc, values, isnull);
3610 /* Preserve OID, if any */
3611 if (newTupDesc->tdhasoid)
3612 HeapTupleSetOid(tuple, tupOid);
3615 /* Now check any constraints on the possibly-changed tuple */
3616 ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
3617 econtext->ecxt_scantuple = newslot;
3619 foreach(l, notnull_attrs)
3621 int attn = lfirst_int(l);
3623 if (heap_attisnull(tuple, attn + 1))
3625 (errcode(ERRCODE_NOT_NULL_VIOLATION),
3626 errmsg("column \"%s\" contains null values",
3627 NameStr(newTupDesc->attrs[attn]->attname))));
3630 foreach(l, tab->constraints)
3632 NewConstraint *con = lfirst(l);
3634 switch (con->contype)
3637 if (!ExecQual(con->qualstate, econtext, true))
3639 (errcode(ERRCODE_CHECK_VIOLATION),
3640 errmsg("check constraint \"%s\" is violated by some row",
3643 case CONSTR_FOREIGN:
3644 /* Nothing to do here */
3647 elog(ERROR, "unrecognized constraint type: %d",
3648 (int) con->contype);
3652 /* Write the tuple out to the new relation */
3654 heap_insert(newrel, tuple, mycid, hi_options, bistate);
3656 ResetExprContext(econtext);
3658 CHECK_FOR_INTERRUPTS();
3661 MemoryContextSwitchTo(oldCxt);
3664 ExecDropSingleTupleTableSlot(oldslot);
3665 ExecDropSingleTupleTableSlot(newslot);
3668 FreeExecutorState(estate);
3670 heap_close(oldrel, NoLock);
3673 FreeBulkInsertState(bistate);
3675 /* If we skipped writing WAL, then we need to sync the heap. */
3676 if (hi_options & HEAP_INSERT_SKIP_WAL)
3679 heap_close(newrel, NoLock);
3684 * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
3686 static AlteredTableInfo *
3687 ATGetQueueEntry(List **wqueue, Relation rel)
3689 Oid relid = RelationGetRelid(rel);
3690 AlteredTableInfo *tab;
3693 foreach(ltab, *wqueue)
3695 tab = (AlteredTableInfo *) lfirst(ltab);
3696 if (tab->relid == relid)
3701 * Not there, so add it. Note that we make a copy of the relation's
3702 * existing descriptor before anything interesting can happen to it.
3704 tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
3706 tab->relkind = rel->rd_rel->relkind;
3707 tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));
3709 *wqueue = lappend(*wqueue, tab);
3715 * ATSimplePermissions
3717 * - Ensure that it is a relation (or possibly a view)
3718 * - Ensure this user is the owner
3719 * - Ensure that it is not a system table
3722 ATSimplePermissions(Relation rel, int allowed_targets)
3726 switch (rel->rd_rel->relkind)
3728 case RELKIND_RELATION:
3729 actual_target = ATT_TABLE;
3732 actual_target = ATT_VIEW;
3735 actual_target = ATT_INDEX;
3737 case RELKIND_COMPOSITE_TYPE:
3738 actual_target = ATT_COMPOSITE_TYPE;
3740 case RELKIND_FOREIGN_TABLE:
3741 actual_target = ATT_FOREIGN_TABLE;
3748 /* Wrong target type? */
3749 if ((actual_target & allowed_targets) == 0)
3750 ATWrongRelkindError(rel, allowed_targets);
3752 /* Permissions checks */
3753 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
3754 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
3755 RelationGetRelationName(rel));
3757 if (!allowSystemTableMods && IsSystemRelation(rel))
3759 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3760 errmsg("permission denied: \"%s\" is a system catalog",
3761 RelationGetRelationName(rel))));
3765 * ATWrongRelkindError
3767 * Throw an error when a relation has been determined to be of the wrong
3771 ATWrongRelkindError(Relation rel, int allowed_targets)
3775 switch (allowed_targets)
3778 msg = _("\"%s\" is not a table");
3780 case ATT_TABLE | ATT_INDEX:
3781 msg = _("\"%s\" is not a table or index");
3783 case ATT_TABLE | ATT_VIEW:
3784 msg = _("\"%s\" is not a table or view");
3786 case ATT_TABLE | ATT_FOREIGN_TABLE:
3787 msg = _("\"%s\" is not a table or foreign table");
3789 case ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE:
3790 msg = _("\"%s\" is not a table, composite type, or foreign table");
3793 msg = _("\"%s\" is not a view");
3795 case ATT_FOREIGN_TABLE:
3796 msg = _("\"%s\" is not a foreign table");
3799 /* shouldn't get here, add all necessary cases above */
3800 msg = _("\"%s\" is of the wrong type");
3805 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3806 errmsg(msg, RelationGetRelationName(rel))));
3812 * Simple table recursion sufficient for most ALTER TABLE operations.
3813 * All direct and indirect children are processed in an unspecified order.
3814 * Note that if a child inherits from the original table via multiple
3815 * inheritance paths, it will be visited just once.
3818 ATSimpleRecursion(List **wqueue, Relation rel,
3819 AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode)
3822 * Propagate to children if desired. Non-table relations never have
3823 * children, so no need to search in that case.
3825 if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
3827 Oid relid = RelationGetRelid(rel);
3831 children = find_all_inheritors(relid, lockmode, NULL);
3834 * find_all_inheritors does the recursive search of the inheritance
3835 * hierarchy, so all we have to do is process all of the relids in the
3836 * list that it returns.
3838 foreach(child, children)
3840 Oid childrelid = lfirst_oid(child);
3843 if (childrelid == relid)
3845 /* find_all_inheritors already got lock */
3846 childrel = relation_open(childrelid, NoLock);
3847 CheckTableNotInUse(childrel, "ALTER TABLE");
3848 ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
3849 relation_close(childrel, NoLock);
3855 * ATTypedTableRecursion
3857 * Propagate ALTER TYPE operations to the typed tables of that type.
3858 * Also check the RESTRICT/CASCADE behavior. Given CASCADE, also permit
3859 * recursion to inheritance children of the typed tables.
3862 ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
3868 Assert(rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
3870 children = find_typed_table_dependencies(rel->rd_rel->reltype,
3871 RelationGetRelationName(rel),
3874 foreach(child, children)
3876 Oid childrelid = lfirst_oid(child);
3879 childrel = relation_open(childrelid, lockmode);
3880 CheckTableNotInUse(childrel, "ALTER TABLE");
3881 ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
3882 relation_close(childrel, NoLock);
3888 * find_composite_type_dependencies
3890 * Check to see if a composite type is being used as a column in some
3891 * other table (possibly nested several levels deep in composite types!).
3892 * Eventually, we'd like to propagate the check or rewrite operation
3893 * into other such tables, but for now, just error out if we find any.
3895 * Caller should provide either a table name or a type name (not both) to
3896 * report in the error message, if any.
3898 * We assume that functions and views depending on the type are not reasons
3899 * to reject the ALTER. (How safe is this really?)
3902 find_composite_type_dependencies(Oid typeOid, Relation origRelation,
3903 const char *origTypeName)
3907 SysScanDesc depScan;
3912 * We scan pg_depend to find those things that depend on the rowtype. (We
3913 * assume we can ignore refobjsubid for a rowtype.)
3915 depRel = heap_open(DependRelationId, AccessShareLock);
3917 ScanKeyInit(&key[0],
3918 Anum_pg_depend_refclassid,
3919 BTEqualStrategyNumber, F_OIDEQ,
3920 ObjectIdGetDatum(TypeRelationId));
3921 ScanKeyInit(&key[1],
3922 Anum_pg_depend_refobjid,
3923 BTEqualStrategyNumber, F_OIDEQ,
3924 ObjectIdGetDatum(typeOid));
3926 depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
3927 SnapshotNow, 2, key);
3929 while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
3931 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
3933 Form_pg_attribute att;
3935 /* Ignore dependees that aren't user columns of relations */
3936 /* (we assume system columns are never of rowtypes) */
3937 if (pg_depend->classid != RelationRelationId ||
3938 pg_depend->objsubid <= 0)
3941 rel = relation_open(pg_depend->objid, AccessShareLock);
3942 att = rel->rd_att->attrs[pg_depend->objsubid - 1];
3944 if (rel->rd_rel->relkind == RELKIND_RELATION)
3948 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3949 errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
3951 RelationGetRelationName(rel),
3952 NameStr(att->attname))));
3953 else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
3955 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3956 errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
3957 RelationGetRelationName(origRelation),
3958 RelationGetRelationName(rel),
3959 NameStr(att->attname))));
3960 else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
3962 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3963 errmsg("cannot alter foreign table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
3964 RelationGetRelationName(origRelation),
3965 RelationGetRelationName(rel),
3966 NameStr(att->attname))));
3969 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3970 errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
3971 RelationGetRelationName(origRelation),
3972 RelationGetRelationName(rel),
3973 NameStr(att->attname))));
3975 else if (OidIsValid(rel->rd_rel->reltype))
3978 * A view or composite type itself isn't a problem, but we must
3979 * recursively check for indirect dependencies via its rowtype.
3981 find_composite_type_dependencies(rel->rd_rel->reltype,
3982 origRelation, origTypeName);
3985 relation_close(rel, AccessShareLock);
3988 systable_endscan(depScan);
3990 relation_close(depRel, AccessShareLock);
3993 * If there's an array type for the rowtype, must check for uses of it,
3996 arrayOid = get_array_type(typeOid);
3997 if (OidIsValid(arrayOid))
3998 find_composite_type_dependencies(arrayOid, origRelation, origTypeName);
4003 * find_typed_table_dependencies
4005 * Check to see if a composite type is being used as the type of a
4006 * typed table. Abort if any are found and behavior is RESTRICT.
4007 * Else return the list of tables.
4010 find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior behavior)
4018 classRel = heap_open(RelationRelationId, AccessShareLock);
4020 ScanKeyInit(&key[0],
4021 Anum_pg_class_reloftype,
4022 BTEqualStrategyNumber, F_OIDEQ,
4023 ObjectIdGetDatum(typeOid));
4025 scan = heap_beginscan(classRel, SnapshotNow, 1, key);
4027 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4029 if (behavior == DROP_RESTRICT)
4031 (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
4032 errmsg("cannot alter type \"%s\" because it is the type of a typed table",
4034 errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
4036 result = lappend_oid(result, HeapTupleGetOid(tuple));
4040 heap_close(classRel, AccessShareLock);
4049 * Check whether a type is suitable for CREATE TABLE OF/ALTER TABLE OF. If it
4050 * isn't suitable, throw an error. Currently, we require that the type
4051 * originated with CREATE TYPE AS. We could support any row type, but doing so
4052 * would require handling a number of extra corner cases in the DDL commands.
4055 check_of_type(HeapTuple typetuple)
4057 Form_pg_type typ = (Form_pg_type) GETSTRUCT(typetuple);
4058 bool typeOk = false;
4060 if (typ->typtype == TYPTYPE_COMPOSITE)
4062 Relation typeRelation;
4064 Assert(OidIsValid(typ->typrelid));
4065 typeRelation = relation_open(typ->typrelid, AccessShareLock);
4066 typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
4068 * Close the parent rel, but keep our AccessShareLock on it until xact
4069 * commit. That will prevent someone else from deleting or ALTERing
4070 * the type before the typed table creation/conversion commits.
4072 relation_close(typeRelation, NoLock);
4076 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4077 errmsg("type %s is not a composite type",
4078 format_type_be(HeapTupleGetOid(typetuple)))));
4083 * ALTER TABLE ADD COLUMN
4085 * Adds an additional attribute to a relation making the assumption that
4086 * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
4087 * AT_AddColumn AlterTableCmd by parse_utilcmd.c and added as independent
4090 * ADD COLUMN cannot use the normal ALTER TABLE recursion mechanism, because we
4091 * have to decide at runtime whether to recurse or not depending on whether we
4092 * actually add a column or merely merge with an existing column. (We can't
4093 * check this in a static pre-pass because it won't handle multiple inheritance
4094 * situations correctly.)
4097 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4098 AlterTableCmd *cmd, LOCKMODE lockmode)
4100 if (rel->rd_rel->reloftype && !recursing)
4102 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4103 errmsg("cannot add column to typed table")));
4105 if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4106 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
4109 cmd->subtype = AT_AddColumnRecurse;
4113 ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
4114 ColumnDef *colDef, bool isOid,
4115 bool recurse, bool recursing, LOCKMODE lockmode)
4117 Oid myrelid = RelationGetRelid(rel);
4121 FormData_pg_attribute attribute;
4124 HeapTuple typeTuple;
4133 /* At top level, permission check was done in ATPrepCmd, else do it */
4135 ATSimplePermissions(rel, ATT_TABLE);
4137 attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
4140 * Are we adding the column to a recursion child? If so, check whether to
4141 * merge with an existing definition for the column. If we do merge, we
4142 * must not recurse. Children will already have the column, and recursing
4143 * into them would mess up attinhcount.
4145 if (colDef->inhcount > 0)
4149 /* Does child already have a column by this name? */
4150 tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
4151 if (HeapTupleIsValid(tuple))
4153 Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
4158 /* Child column must match on type, typmod, and collation */
4159 typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
4160 if (ctypeId != childatt->atttypid ||
4161 ctypmod != childatt->atttypmod)
4163 (errcode(ERRCODE_DATATYPE_MISMATCH),
4164 errmsg("child table \"%s\" has different type for column \"%s\"",
4165 RelationGetRelationName(rel), colDef->colname)));
4166 ccollid = GetColumnDefCollation(NULL, colDef, ctypeId);
4167 if (ccollid != childatt->attcollation)
4169 (errcode(ERRCODE_COLLATION_MISMATCH),
4170 errmsg("child table \"%s\" has different collation for column \"%s\"",
4171 RelationGetRelationName(rel), colDef->colname),
4172 errdetail("\"%s\" versus \"%s\"",
4173 get_collation_name(ccollid),
4174 get_collation_name(childatt->attcollation))));
4176 /* If it's OID, child column must actually be OID */
4177 if (isOid && childatt->attnum != ObjectIdAttributeNumber)
4179 (errcode(ERRCODE_DATATYPE_MISMATCH),
4180 errmsg("child table \"%s\" has a conflicting \"%s\" column",
4181 RelationGetRelationName(rel), colDef->colname)));
4183 /* Bump the existing child att's inhcount */
4184 childatt->attinhcount++;
4185 simple_heap_update(attrdesc, &tuple->t_self, tuple);
4186 CatalogUpdateIndexes(attrdesc, tuple);
4188 heap_freetuple(tuple);
4190 /* Inform the user about the merge */
4192 (errmsg("merging definition of column \"%s\" for child \"%s\"",
4193 colDef->colname, RelationGetRelationName(rel))));
4195 heap_close(attrdesc, RowExclusiveLock);
4200 pgclass = heap_open(RelationRelationId, RowExclusiveLock);
4202 reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
4203 if (!HeapTupleIsValid(reltup))
4204 elog(ERROR, "cache lookup failed for relation %u", myrelid);
4205 relkind = ((Form_pg_class) GETSTRUCT(reltup))->relkind;
4208 * this test is deliberately not attisdropped-aware, since if one tries to
4209 * add a column matching a dropped column name, it's gonna fail anyway.
4211 if (SearchSysCacheExists2(ATTNAME,
4212 ObjectIdGetDatum(myrelid),
4213 PointerGetDatum(colDef->colname)))
4215 (errcode(ERRCODE_DUPLICATE_COLUMN),
4216 errmsg("column \"%s\" of relation \"%s\" already exists",
4217 colDef->colname, RelationGetRelationName(rel))));
4219 /* Determine the new attribute's number */
4221 newattnum = ObjectIdAttributeNumber;
4224 newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
4225 if (newattnum > MaxHeapAttributeNumber)
4227 (errcode(ERRCODE_TOO_MANY_COLUMNS),
4228 errmsg("tables can have at most %d columns",
4229 MaxHeapAttributeNumber)));
4232 typeTuple = typenameType(NULL, colDef->typeName, &typmod);
4233 tform = (Form_pg_type) GETSTRUCT(typeTuple);
4234 typeOid = HeapTupleGetOid(typeTuple);
4235 collOid = GetColumnDefCollation(NULL, colDef, typeOid);
4237 /* make sure datatype is legal for a column */
4238 CheckAttributeType(colDef->colname, typeOid, collOid,
4239 list_make1_oid(rel->rd_rel->reltype),
4242 /* construct new attribute's pg_attribute entry */
4243 attribute.attrelid = myrelid;
4244 namestrcpy(&(attribute.attname), colDef->colname);
4245 attribute.atttypid = typeOid;
4246 attribute.attstattarget = (newattnum > 0) ? -1 : 0;
4247 attribute.attlen = tform->typlen;
4248 attribute.attcacheoff = -1;
4249 attribute.atttypmod = typmod;
4250 attribute.attnum = newattnum;
4251 attribute.attbyval = tform->typbyval;
4252 attribute.attndims = list_length(colDef->typeName->arrayBounds);
4253 attribute.attstorage = tform->typstorage;
4254 attribute.attalign = tform->typalign;
4255 attribute.attnotnull = colDef->is_not_null;
4256 attribute.atthasdef = false;
4257 attribute.attisdropped = false;
4258 attribute.attislocal = colDef->is_local;
4259 attribute.attinhcount = colDef->inhcount;
4260 attribute.attcollation = collOid;
4261 /* attribute.attacl is handled by InsertPgAttributeTuple */
4263 ReleaseSysCache(typeTuple);
4265 InsertPgAttributeTuple(attrdesc, &attribute, NULL);
4267 heap_close(attrdesc, RowExclusiveLock);
4270 * Update pg_class tuple as appropriate
4273 ((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true;
4275 ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
4277 simple_heap_update(pgclass, &reltup->t_self, reltup);
4279 /* keep catalog indexes current */
4280 CatalogUpdateIndexes(pgclass, reltup);
4282 heap_freetuple(reltup);
4284 /* Post creation hook for new attribute */
4285 InvokeObjectAccessHook(OAT_POST_CREATE,
4286 RelationRelationId, myrelid, newattnum);
4288 heap_close(pgclass, RowExclusiveLock);
4290 /* Make the attribute's catalog entry visible */
4291 CommandCounterIncrement();
4294 * Store the DEFAULT, if any, in the catalogs
4296 if (colDef->raw_default)
4298 RawColumnDefault *rawEnt;
4300 if (relkind == RELKIND_FOREIGN_TABLE)
4302 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4303 errmsg("default values on foreign tables are not supported")));
4305 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
4306 rawEnt->attnum = attribute.attnum;
4307 rawEnt->raw_default = copyObject(colDef->raw_default);
4310 * This function is intended for CREATE TABLE, so it processes a
4311 * _list_ of defaults, but we just do one.
4313 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
4315 /* Make the additional catalog changes visible */
4316 CommandCounterIncrement();
4320 * Tell Phase 3 to fill in the default expression, if there is one.
4322 * If there is no default, Phase 3 doesn't have to do anything, because
4323 * that effectively means that the default is NULL. The heap tuple access
4324 * routines always check for attnum > # of attributes in tuple, and return
4325 * NULL if so, so without any modification of the tuple data we will get
4326 * the effect of NULL values in the new column.
4328 * An exception occurs when the new column is of a domain type: the domain
4329 * might have a NOT NULL constraint, or a check constraint that indirectly
4330 * rejects nulls. If there are any domain constraints then we construct
4331 * an explicit NULL default value that will be passed through
4332 * CoerceToDomain processing. (This is a tad inefficient, since it causes
4333 * rewriting the table which we really don't have to do, but the present
4334 * design of domain processing doesn't offer any simple way of checking
4335 * the constraints more directly.)
4337 * Note: we use build_column_default, and not just the cooked default
4338 * returned by AddRelationNewConstraints, so that the right thing happens
4339 * when a datatype's default applies.
4341 * We skip this step completely for views and foreign tables. For a view,
4342 * we can only get here from CREATE OR REPLACE VIEW, which historically
4343 * doesn't set up defaults, not even for domain-typed columns. And in any
4344 * case we mustn't invoke Phase 3 on a view or foreign table, since they
4347 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE
4348 && relkind != RELKIND_FOREIGN_TABLE && attribute.attnum > 0)
4350 defval = (Expr *) build_column_default(rel, attribute.attnum);
4352 if (!defval && GetDomainConstraints(typeOid) != NIL)
4358 baseTypeMod = typmod;
4359 baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
4360 baseTypeColl = get_typcollation(baseTypeId);
4361 defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
4362 defval = (Expr *) coerce_to_target_type(NULL,
4367 COERCION_ASSIGNMENT,
4368 COERCE_IMPLICIT_CAST,
4370 if (defval == NULL) /* should not happen */
4371 elog(ERROR, "failed to coerce base type to domain");
4376 NewColumnValue *newval;
4378 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
4379 newval->attnum = attribute.attnum;
4380 newval->expr = defval;
4382 tab->newvals = lappend(tab->newvals, newval);
4383 tab->rewrite = true;
4387 * If the new column is NOT NULL, tell Phase 3 it needs to test that.
4388 * (Note we don't do this for an OID column. OID will be marked not
4389 * null, but since it's filled specially, there's no need to test
4392 tab->new_notnull |= colDef->is_not_null;
4396 * If we are adding an OID column, we have to tell Phase 3 to rewrite the
4397 * table to fix that.
4400 tab->rewrite = true;
4403 * Add needed dependency entries for the new column.
4405 add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
4406 add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);
4409 * Propagate to children as appropriate. Unlike most other ALTER
4410 * routines, we have to do this one level of recursion at a time; we can't
4411 * use find_all_inheritors to do it in one pass.
4413 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
4416 * If we are told not to recurse, there had better not be any child
4417 * tables; else the addition would put them out of step.
4419 if (children && !recurse)
4421 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4422 errmsg("column must be added to child tables too")));
4424 /* Children should see column as singly inherited */
4427 colDef = copyObject(colDef);
4428 colDef->inhcount = 1;
4429 colDef->is_local = false;
4432 foreach(child, children)
4434 Oid childrelid = lfirst_oid(child);
4436 AlteredTableInfo *childtab;
4438 /* find_inheritance_children already got lock */
4439 childrel = heap_open(childrelid, NoLock);
4440 CheckTableNotInUse(childrel, "ALTER TABLE");
4442 /* Find or create work queue entry for this table */
4443 childtab = ATGetQueueEntry(wqueue, childrel);
4445 /* Recurse to child */
4446 ATExecAddColumn(wqueue, childtab, childrel,
4447 colDef, isOid, recurse, true, lockmode);
4449 heap_close(childrel, NoLock);
4454 * Install a column's dependency on its datatype.
4457 add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
4459 ObjectAddress myself,
4462 myself.classId = RelationRelationId;
4463 myself.objectId = relid;
4464 myself.objectSubId = attnum;
4465 referenced.classId = TypeRelationId;
4466 referenced.objectId = typid;
4467 referenced.objectSubId = 0;
4468 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4472 * Install a column's dependency on its collation.
4475 add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
4477 ObjectAddress myself,
4480 /* We know the default collation is pinned, so don't bother recording it */
4481 if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID)
4483 myself.classId = RelationRelationId;
4484 myself.objectId = relid;
4485 myself.objectSubId = attnum;
4486 referenced.classId = CollationRelationId;
4487 referenced.objectId = collid;
4488 referenced.objectSubId = 0;
4489 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4494 * ALTER TABLE SET WITH OIDS
4496 * Basically this is an ADD COLUMN for the special OID column. We have
4497 * to cons up a ColumnDef node because the ADD COLUMN code needs one.
4500 ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode)
4502 /* If we're recursing to a child table, the ColumnDef is already set up */
4503 if (cmd->def == NULL)
4505 ColumnDef *cdef = makeNode(ColumnDef);
4507 cdef->colname = pstrdup("oid");
4508 cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
4510 cdef->is_local = true;
4511 cdef->is_not_null = true;
4513 cmd->def = (Node *) cdef;
4515 ATPrepAddColumn(wqueue, rel, recurse, false, cmd, lockmode);
4518 cmd->subtype = AT_AddOidsRecurse;
4522 * ALTER TABLE ALTER COLUMN DROP NOT NULL
4525 ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
4531 ListCell *indexoidscan;
4534 * lookup the attribute
4536 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4538 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4540 if (!HeapTupleIsValid(tuple))
4542 (errcode(ERRCODE_UNDEFINED_COLUMN),
4543 errmsg("column \"%s\" of relation \"%s\" does not exist",
4544 colName, RelationGetRelationName(rel))));
4546 attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4548 /* Prevent them from altering a system attribute */
4551 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4552 errmsg("cannot alter system column \"%s\"",
4556 * Check that the attribute is not in a primary key
4559 /* Loop over all indexes on the relation */
4560 indexoidlist = RelationGetIndexList(rel);
4562 foreach(indexoidscan, indexoidlist)
4564 Oid indexoid = lfirst_oid(indexoidscan);
4565 HeapTuple indexTuple;
4566 Form_pg_index indexStruct;
4569 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
4570 if (!HeapTupleIsValid(indexTuple))
4571 elog(ERROR, "cache lookup failed for index %u", indexoid);
4572 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4574 /* If the index is not a primary key, skip the check */
4575 if (indexStruct->indisprimary)
4578 * Loop over each attribute in the primary key and see if it
4579 * matches the to-be-altered attribute
4581 for (i = 0; i < indexStruct->indnatts; i++)
4583 if (indexStruct->indkey.values[i] == attnum)
4585 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4586 errmsg("column \"%s\" is in a primary key",
4591 ReleaseSysCache(indexTuple);
4594 list_free(indexoidlist);
4597 * Okay, actually perform the catalog change ... if needed
4599 if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4601 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;
4603 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4605 /* keep the system catalog indexes current */
4606 CatalogUpdateIndexes(attr_rel, tuple);
4609 heap_close(attr_rel, RowExclusiveLock);
4613 * ALTER TABLE ALTER COLUMN SET NOT NULL
4616 ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
4617 const char *colName, LOCKMODE lockmode)
4624 * lookup the attribute
4626 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4628 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4630 if (!HeapTupleIsValid(tuple))
4632 (errcode(ERRCODE_UNDEFINED_COLUMN),
4633 errmsg("column \"%s\" of relation \"%s\" does not exist",
4634 colName, RelationGetRelationName(rel))));
4636 attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4638 /* Prevent them from altering a system attribute */
4641 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4642 errmsg("cannot alter system column \"%s\"",
4646 * Okay, actually perform the catalog change ... if needed
4648 if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4650 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;
4652 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4654 /* keep the system catalog indexes current */
4655 CatalogUpdateIndexes(attr_rel, tuple);
4657 /* Tell Phase 3 it needs to test the constraint */
4658 tab->new_notnull = true;
4661 heap_close(attr_rel, RowExclusiveLock);
4665 * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
4668 ATExecColumnDefault(Relation rel, const char *colName,
4669 Node *newDefault, LOCKMODE lockmode)
4674 * get the number of the attribute
4676 attnum = get_attnum(RelationGetRelid(rel), colName);
4677 if (attnum == InvalidAttrNumber)
4679 (errcode(ERRCODE_UNDEFINED_COLUMN),
4680 errmsg("column \"%s\" of relation \"%s\" does not exist",
4681 colName, RelationGetRelationName(rel))));
4683 /* Prevent them from altering a system attribute */
4686 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4687 errmsg("cannot alter system column \"%s\"",
4691 * Remove any old default for the column. We use RESTRICT here for
4692 * safety, but at present we do not expect anything to depend on the
4695 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
4700 RawColumnDefault *rawEnt;
4702 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
4703 rawEnt->attnum = attnum;
4704 rawEnt->raw_default = newDefault;
4707 * This function is intended for CREATE TABLE, so it processes a
4708 * _list_ of defaults, but we just do one.
4710 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
4715 * ALTER TABLE ALTER COLUMN SET STATISTICS
4718 ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4721 * We do our own permission checking because (a) we want to allow SET
4722 * STATISTICS on indexes (for expressional index columns), and (b) we want
4723 * to allow SET STATISTICS on system catalogs without requiring
4724 * allowSystemTableMods to be turned on.
4726 if (rel->rd_rel->relkind != RELKIND_RELATION &&
4727 rel->rd_rel->relkind != RELKIND_INDEX)
4729 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4730 errmsg("\"%s\" is not a table or index",
4731 RelationGetRelationName(rel))));
4733 /* Permissions checks */
4734 if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
4735 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
4736 RelationGetRelationName(rel));
4740 ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4743 Relation attrelation;
4745 Form_pg_attribute attrtuple;
4747 Assert(IsA(newValue, Integer));
4748 newtarget = intVal(newValue);
4751 * Limit target to a sane range
4756 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4757 errmsg("statistics target %d is too low",
4760 else if (newtarget > 10000)
4764 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4765 errmsg("lowering statistics target to %d",
4769 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4771 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4773 if (!HeapTupleIsValid(tuple))
4775 (errcode(ERRCODE_UNDEFINED_COLUMN),
4776 errmsg("column \"%s\" of relation \"%s\" does not exist",
4777 colName, RelationGetRelationName(rel))));
4778 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4780 if (attrtuple->attnum <= 0)
4782 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4783 errmsg("cannot alter system column \"%s\"",
4786 attrtuple->attstattarget = newtarget;
4788 simple_heap_update(attrelation, &tuple->t_self, tuple);
4790 /* keep system catalog indexes current */
4791 CatalogUpdateIndexes(attrelation, tuple);
4793 heap_freetuple(tuple);
4795 heap_close(attrelation, RowExclusiveLock);
4799 ATExecSetOptions(Relation rel, const char *colName, Node *options,
4800 bool isReset, LOCKMODE lockmode)
4802 Relation attrelation;
4805 Form_pg_attribute attrtuple;
4809 Datum repl_val[Natts_pg_attribute];
4810 bool repl_null[Natts_pg_attribute];
4811 bool repl_repl[Natts_pg_attribute];
4813 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4815 tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4817 if (!HeapTupleIsValid(tuple))
4819 (errcode(ERRCODE_UNDEFINED_COLUMN),
4820 errmsg("column \"%s\" of relation \"%s\" does not exist",
4821 colName, RelationGetRelationName(rel))));
4822 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4824 if (attrtuple->attnum <= 0)
4826 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4827 errmsg("cannot alter system column \"%s\"",
4830 /* Generate new proposed attoptions (text array) */
4831 Assert(IsA(options, List));
4832 datum = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions,
4834 newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
4835 (List *) options, NULL, NULL, false,
4837 /* Validate new options */
4838 (void) attribute_reloptions(newOptions, true);
4840 /* Build new tuple. */
4841 memset(repl_null, false, sizeof(repl_null));
4842 memset(repl_repl, false, sizeof(repl_repl));
4843 if (newOptions != (Datum) 0)
4844 repl_val[Anum_pg_attribute_attoptions - 1] = newOptions;
4846 repl_null[Anum_pg_attribute_attoptions - 1] = true;
4847 repl_repl[Anum_pg_attribute_attoptions - 1] = true;
4848 newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation),
4849 repl_val, repl_null, repl_repl);
4850 ReleaseSysCache(tuple);
4852 /* Update system catalog. */
4853 simple_heap_update(attrelation, &newtuple->t_self, newtuple);
4854 CatalogUpdateIndexes(attrelation, newtuple);
4855 heap_freetuple(newtuple);
4857 heap_close(attrelation, RowExclusiveLock);
4861 * ALTER TABLE ALTER COLUMN SET STORAGE
4864 ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4868 Relation attrelation;
4870 Form_pg_attribute attrtuple;
4872 Assert(IsA(newValue, String));
4873 storagemode = strVal(newValue);
4875 if (pg_strcasecmp(storagemode, "plain") == 0)
4877 else if (pg_strcasecmp(storagemode, "external") == 0)
4879 else if (pg_strcasecmp(storagemode, "extended") == 0)
4881 else if (pg_strcasecmp(storagemode, "main") == 0)
4886 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4887 errmsg("invalid storage type \"%s\"",
4889 newstorage = 0; /* keep compiler quiet */
4892 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4894 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4896 if (!HeapTupleIsValid(tuple))
4898 (errcode(ERRCODE_UNDEFINED_COLUMN),
4899 errmsg("column \"%s\" of relation \"%s\" does not exist",
4900 colName, RelationGetRelationName(rel))));
4901 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4903 if (attrtuple->attnum <= 0)
4905 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4906 errmsg("cannot alter system column \"%s\"",
4910 * safety check: do not allow toasted storage modes unless column datatype
4913 if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
4914 attrtuple->attstorage = newstorage;
4917 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4918 errmsg("column data type %s can only have storage PLAIN",
4919 format_type_be(attrtuple->atttypid))));
4921 simple_heap_update(attrelation, &tuple->t_self, tuple);
4923 /* keep system catalog indexes current */
4924 CatalogUpdateIndexes(attrelation, tuple);
4926 heap_freetuple(tuple);
4928 heap_close(attrelation, RowExclusiveLock);
4933 * ALTER TABLE DROP COLUMN
4935 * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
4936 * because we have to decide at runtime whether to recurse or not depending
4937 * on whether attinhcount goes to zero or not. (We can't check this in a
4938 * static pre-pass because it won't handle multiple inheritance situations
4942 ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4943 AlterTableCmd *cmd, LOCKMODE lockmode)
4945 if (rel->rd_rel->reloftype && !recursing)
4947 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4948 errmsg("cannot drop column from typed table")));
4950 if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4951 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
4954 cmd->subtype = AT_DropColumnRecurse;
4958 ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
4959 DropBehavior behavior,
4960 bool recurse, bool recursing,
4961 bool missing_ok, LOCKMODE lockmode)
4964 Form_pg_attribute targetatt;
4967 ObjectAddress object;
4969 /* At top level, permission check was done in ATPrepCmd, else do it */
4971 ATSimplePermissions(rel, ATT_TABLE);
4974 * get the number of the attribute
4976 tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4977 if (!HeapTupleIsValid(tuple))
4982 (errcode(ERRCODE_UNDEFINED_COLUMN),
4983 errmsg("column \"%s\" of relation \"%s\" does not exist",
4984 colName, RelationGetRelationName(rel))));
4989 (errmsg("column \"%s\" of relation \"%s\" does not exist, skipping",
4990 colName, RelationGetRelationName(rel))));
4994 targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
4996 attnum = targetatt->attnum;
4998 /* Can't drop a system attribute, except OID */
4999 if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
5001 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5002 errmsg("cannot drop system column \"%s\"",
5005 /* Don't drop inherited columns */
5006 if (targetatt->attinhcount > 0 && !recursing)
5008 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5009 errmsg("cannot drop inherited column \"%s\"",
5012 ReleaseSysCache(tuple);
5015 * Propagate to children as appropriate. Unlike most other ALTER
5016 * routines, we have to do this one level of recursion at a time; we can't
5017 * use find_all_inheritors to do it in one pass.
5019 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5026 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
5027 foreach(child, children)
5029 Oid childrelid = lfirst_oid(child);
5031 Form_pg_attribute childatt;
5033 /* find_inheritance_children already got lock */
5034 childrel = heap_open(childrelid, NoLock);
5035 CheckTableNotInUse(childrel, "ALTER TABLE");
5037 tuple = SearchSysCacheCopyAttName(childrelid, colName);
5038 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
5039 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
5040 colName, childrelid);
5041 childatt = (Form_pg_attribute) GETSTRUCT(tuple);
5043 if (childatt->attinhcount <= 0) /* shouldn't happen */
5044 elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
5045 childrelid, colName);
5050 * If the child column has other definition sources, just
5051 * decrement its inheritance count; if not, recurse to delete
5054 if (childatt->attinhcount == 1 && !childatt->attislocal)
5056 /* Time to delete this child column, too */
5057 ATExecDropColumn(wqueue, childrel, colName,
5058 behavior, true, true,
5063 /* Child column must survive my deletion */
5064 childatt->attinhcount--;
5066 simple_heap_update(attr_rel, &tuple->t_self, tuple);
5068 /* keep the system catalog indexes current */
5069 CatalogUpdateIndexes(attr_rel, tuple);
5071 /* Make update visible */
5072 CommandCounterIncrement();
5078 * If we were told to drop ONLY in this table (no recursion),
5079 * we need to mark the inheritors' attributes as locally
5080 * defined rather than inherited.
5082 childatt->attinhcount--;
5083 childatt->attislocal = true;
5085 simple_heap_update(attr_rel, &tuple->t_self, tuple);
5087 /* keep the system catalog indexes current */
5088 CatalogUpdateIndexes(attr_rel, tuple);
5090 /* Make update visible */
5091 CommandCounterIncrement();
5094 heap_freetuple(tuple);
5096 heap_close(childrel, NoLock);
5098 heap_close(attr_rel, RowExclusiveLock);
5102 * Perform the actual column deletion
5104 object.classId = RelationRelationId;
5105 object.objectId = RelationGetRelid(rel);
5106 object.objectSubId = attnum;
5108 performDeletion(&object, behavior);
5111 * If we dropped the OID column, must adjust pg_class.relhasoids and tell
5112 * Phase 3 to physically get rid of the column. We formerly left the
5113 * column in place physically, but this caused subtle problems. See
5114 * http://archives.postgresql.org/pgsql-hackers/2009-02/msg00363.php
5116 if (attnum == ObjectIdAttributeNumber)
5119 Form_pg_class tuple_class;
5120 AlteredTableInfo *tab;
5122 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5124 tuple = SearchSysCacheCopy1(RELOID,
5125 ObjectIdGetDatum(RelationGetRelid(rel)));
5126 if (!HeapTupleIsValid(tuple))
5127 elog(ERROR, "cache lookup failed for relation %u",
5128 RelationGetRelid(rel));
5129 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
5131 tuple_class->relhasoids = false;
5132 simple_heap_update(class_rel, &tuple->t_self, tuple);
5134 /* Keep the catalog indexes up to date */
5135 CatalogUpdateIndexes(class_rel, tuple);
5137 heap_close(class_rel, RowExclusiveLock);
5139 /* Find or create work queue entry for this table */
5140 tab = ATGetQueueEntry(wqueue, rel);
5142 /* Tell Phase 3 to physically remove the OID column */
5143 tab->rewrite = true;
5148 * ALTER TABLE ADD INDEX
5150 * There is no such command in the grammar, but parse_utilcmd.c converts
5151 * UNIQUE and PRIMARY KEY constraints into AT_AddIndex subcommands. This lets
5152 * us schedule creation of the index at the appropriate time during ALTER.
5155 ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
5156 IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode)
5162 Assert(IsA(stmt, IndexStmt));
5164 /* suppress schema rights check when rebuilding existing index */
5165 check_rights = !is_rebuild;
5166 /* skip index build if phase 3 will have to rewrite table anyway */
5167 skip_build = tab->rewrite;
5168 /* suppress notices when rebuilding existing index */
5171 /* The IndexStmt has already been through transformIndexStmt */
5173 DefineIndex(stmt->relation, /* relation */
5174 stmt->idxname, /* index name */
5175 InvalidOid, /* no predefined OID */
5176 stmt->accessMethod, /* am name */
5178 stmt->indexParams, /* parameters */
5179 (Expr *) stmt->whereClause,
5181 stmt->excludeOpNames,
5187 true, /* is_alter_table */
5195 * ALTER TABLE ADD CONSTRAINT USING INDEX
5198 ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
5199 IndexStmt *stmt, LOCKMODE lockmode)
5201 Oid index_oid = stmt->indexOid;
5204 IndexInfo *indexInfo;
5205 char *constraintName;
5206 char constraintType;
5208 Assert(IsA(stmt, IndexStmt));
5209 Assert(OidIsValid(index_oid));
5210 Assert(stmt->isconstraint);
5212 indexRel = index_open(index_oid, AccessShareLock);
5214 indexName = pstrdup(RelationGetRelationName(indexRel));
5216 indexInfo = BuildIndexInfo(indexRel);
5218 /* this should have been checked at parse time */
5219 if (!indexInfo->ii_Unique)
5220 elog(ERROR, "index \"%s\" is not unique", indexName);
5223 * Determine name to assign to constraint. We require a constraint to
5224 * have the same name as the underlying index; therefore, use the index's
5225 * existing name as the default constraint name, and if the user
5226 * explicitly gives some other name for the constraint, rename the index
5229 constraintName = stmt->idxname;
5230 if (constraintName == NULL)
5231 constraintName = indexName;
5232 else if (strcmp(constraintName, indexName) != 0)
5235 (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"",
5236 indexName, constraintName)));
5237 RenameRelation(index_oid, constraintName, OBJECT_INDEX);
5240 /* Extra checks needed if making primary key */
5242 index_check_primary_key(rel, indexInfo, true);
5244 /* Note we currently don't support EXCLUSION constraints here */
5246 constraintType = CONSTRAINT_PRIMARY;
5248 constraintType = CONSTRAINT_UNIQUE;
5250 /* Create the catalog entries for the constraint */
5251 index_constraint_create(rel,
5260 allowSystemTableMods);
5262 index_close(indexRel, NoLock);
5266 * ALTER TABLE ADD CONSTRAINT
5269 ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5270 Constraint *newConstraint, bool recurse, LOCKMODE lockmode)
5272 Assert(IsA(newConstraint, Constraint));
5275 * Currently, we only expect to see CONSTR_CHECK and CONSTR_FOREIGN nodes
5276 * arriving here (see the preprocessing done in parse_utilcmd.c). Use a
5277 * switch anyway to make it easier to add more code later.
5279 switch (newConstraint->contype)
5282 ATAddCheckConstraint(wqueue, tab, rel,
5283 newConstraint, recurse, false, lockmode);
5286 case CONSTR_FOREIGN:
5289 * Note that we currently never recurse for FK constraints, so the
5290 * "recurse" flag is silently ignored.
5292 * Assign or validate constraint name
5294 if (newConstraint->conname)
5296 if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
5297 RelationGetRelid(rel),
5298 RelationGetNamespace(rel),
5299 newConstraint->conname))
5301 (errcode(ERRCODE_DUPLICATE_OBJECT),
5302 errmsg("constraint \"%s\" for relation \"%s\" already exists",
5303 newConstraint->conname,
5304 RelationGetRelationName(rel))));
5307 newConstraint->conname =
5308 ChooseConstraintName(RelationGetRelationName(rel),
5309 strVal(linitial(newConstraint->fk_attrs)),
5311 RelationGetNamespace(rel),
5314 ATAddForeignKeyConstraint(tab, rel, newConstraint, lockmode);
5318 elog(ERROR, "unrecognized constraint type: %d",
5319 (int) newConstraint->contype);
5324 * Add a check constraint to a single table and its children
5326 * Subroutine for ATExecAddConstraint.
5328 * We must recurse to child tables during execution, rather than using
5329 * ALTER TABLE's normal prep-time recursion. The reason is that all the
5330 * constraints *must* be given the same name, else they won't be seen as
5331 * related later. If the user didn't explicitly specify a name, then
5332 * AddRelationNewConstraints would normally assign different names to the
5333 * child constraints. To fix that, we must capture the name assigned at
5334 * the parent table and pass that down.
5337 ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5338 Constraint *constr, bool recurse, bool recursing,
5346 /* At top level, permission check was done in ATPrepCmd, else do it */
5348 ATSimplePermissions(rel, ATT_TABLE);
5351 * Call AddRelationNewConstraints to do the work, making sure it works on
5352 * a copy of the Constraint so transformExpr can't modify the original. It
5353 * returns a list of cooked constraints.
5355 * If the constraint ends up getting merged with a pre-existing one, it's
5356 * omitted from the returned list, which is what we want: we do not need
5357 * to do any validation work. That can only happen at child tables,
5358 * though, since we disallow merging at the top level.
5360 newcons = AddRelationNewConstraints(rel, NIL,
5361 list_make1(copyObject(constr)),
5362 recursing, !recursing);
5364 /* Add each constraint to Phase 3's queue */
5365 foreach(lcon, newcons)
5367 CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
5368 NewConstraint *newcon;
5370 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
5371 newcon->name = ccon->name;
5372 newcon->contype = ccon->contype;
5373 /* ExecQual wants implicit-AND format */
5374 newcon->qual = (Node *) make_ands_implicit((Expr *) ccon->expr);
5376 tab->constraints = lappend(tab->constraints, newcon);
5378 /* Save the actually assigned name if it was defaulted */
5379 if (constr->conname == NULL)
5380 constr->conname = ccon->name;
5383 /* At this point we must have a locked-down name to use */
5384 Assert(constr->conname != NULL);
5386 /* Advance command counter in case same table is visited multiple times */
5387 CommandCounterIncrement();
5390 * If the constraint got merged with an existing constraint, we're done.
5391 * We mustn't recurse to child tables in this case, because they've
5392 * already got the constraint, and visiting them again would lead to an
5393 * incorrect value for coninhcount.
5399 * Propagate to children as appropriate. Unlike most other ALTER
5400 * routines, we have to do this one level of recursion at a time; we can't
5401 * use find_all_inheritors to do it in one pass.
5403 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5406 * If we are told not to recurse, there had better not be any child
5407 * tables; else the addition would put them out of step.
5409 if (children && !recurse)
5411 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5412 errmsg("constraint must be added to child tables too")));
5414 foreach(child, children)
5416 Oid childrelid = lfirst_oid(child);
5418 AlteredTableInfo *childtab;
5420 /* find_inheritance_children already got lock */
5421 childrel = heap_open(childrelid, NoLock);
5422 CheckTableNotInUse(childrel, "ALTER TABLE");
5424 /* Find or create work queue entry for this table */
5425 childtab = ATGetQueueEntry(wqueue, childrel);
5427 /* Recurse to child */
5428 ATAddCheckConstraint(wqueue, childtab, childrel,
5429 constr, recurse, true, lockmode);
5431 heap_close(childrel, NoLock);
5436 * Add a foreign-key constraint to a single table
5438 * Subroutine for ATExecAddConstraint. Must already hold exclusive
5439 * lock on the rel, and have done appropriate validity checks for it.
5440 * We do permissions checks here, however.
5443 ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
5444 Constraint *fkconstraint, LOCKMODE lockmode)
5447 int16 pkattnum[INDEX_MAX_KEYS];
5448 int16 fkattnum[INDEX_MAX_KEYS];
5449 Oid pktypoid[INDEX_MAX_KEYS];
5450 Oid fktypoid[INDEX_MAX_KEYS];
5451 Oid opclasses[INDEX_MAX_KEYS];
5452 Oid pfeqoperators[INDEX_MAX_KEYS];
5453 Oid ppeqoperators[INDEX_MAX_KEYS];
5454 Oid ffeqoperators[INDEX_MAX_KEYS];
5461 pkrel = heap_openrv(fkconstraint->pktable, lockmode);
5464 * Validity checks (permission checks wait till we have the column
5467 if (pkrel->rd_rel->relkind != RELKIND_RELATION)
5469 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5470 errmsg("referenced relation \"%s\" is not a table",
5471 RelationGetRelationName(pkrel))));
5473 if (!allowSystemTableMods && IsSystemRelation(pkrel))
5475 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5476 errmsg("permission denied: \"%s\" is a system catalog",
5477 RelationGetRelationName(pkrel))));
5480 * References from permanent or unlogged tables to temp tables, and from
5481 * permanent tables to unlogged tables, are disallowed because the
5482 * referenced data can vanish out from under us. References from temp
5483 * tables to any other table type are also disallowed, because other
5484 * backends might need to run the RI triggers on the perm table, but they
5485 * can't reliably see tuples in the local buffers of other backends.
5487 switch (rel->rd_rel->relpersistence)
5489 case RELPERSISTENCE_PERMANENT:
5490 if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT)
5492 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5493 errmsg("constraints on permanent tables may reference only permanent tables")));
5495 case RELPERSISTENCE_UNLOGGED:
5496 if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT
5497 && pkrel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED)
5499 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5500 errmsg("constraints on unlogged tables may reference only permanent or unlogged tables")));
5502 case RELPERSISTENCE_TEMP:
5503 if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
5505 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5506 errmsg("constraints on temporary tables may reference only temporary tables")));
5511 * Look up the referencing attributes to make sure they exist, and record
5512 * their attnums and type OIDs.
5514 MemSet(pkattnum, 0, sizeof(pkattnum));
5515 MemSet(fkattnum, 0, sizeof(fkattnum));
5516 MemSet(pktypoid, 0, sizeof(pktypoid));
5517 MemSet(fktypoid, 0, sizeof(fktypoid));
5518 MemSet(opclasses, 0, sizeof(opclasses));
5519 MemSet(pfeqoperators, 0, sizeof(pfeqoperators));
5520 MemSet(ppeqoperators, 0, sizeof(ppeqoperators));
5521 MemSet(ffeqoperators, 0, sizeof(ffeqoperators));
5523 numfks = transformColumnNameList(RelationGetRelid(rel),
5524 fkconstraint->fk_attrs,
5525 fkattnum, fktypoid);
5528 * If the attribute list for the referenced table was omitted, lookup the
5529 * definition of the primary key and use it. Otherwise, validate the
5530 * supplied attribute list. In either case, discover the index OID and
5531 * index opclasses, and the attnums and type OIDs of the attributes.
5533 if (fkconstraint->pk_attrs == NIL)
5535 numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
5536 &fkconstraint->pk_attrs,
5542 numpks = transformColumnNameList(RelationGetRelid(pkrel),
5543 fkconstraint->pk_attrs,
5544 pkattnum, pktypoid);
5545 /* Look for an index matching the column list */
5546 indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
5551 * Now we can check permissions.
5553 checkFkeyPermissions(pkrel, pkattnum, numpks);
5554 checkFkeyPermissions(rel, fkattnum, numfks);
5557 * Look up the equality operators to use in the constraint.
5559 * Note that we have to be careful about the difference between the actual
5560 * PK column type and the opclass' declared input type, which might be
5561 * only binary-compatible with it. The declared opcintype is the right
5562 * thing to probe pg_amop with.
5564 if (numfks != numpks)
5566 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
5567 errmsg("number of referencing and referenced columns for foreign key disagree")));
5569 for (i = 0; i < numpks; i++)
5571 Oid pktype = pktypoid[i];
5572 Oid fktype = fktypoid[i];
5575 Form_pg_opclass cla_tup;
5584 /* We need several fields out of the pg_opclass entry */
5585 cla_ht = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclasses[i]));
5586 if (!HeapTupleIsValid(cla_ht))
5587 elog(ERROR, "cache lookup failed for opclass %u", opclasses[i]);
5588 cla_tup = (Form_pg_opclass) GETSTRUCT(cla_ht);
5589 amid = cla_tup->opcmethod;
5590 opfamily = cla_tup->opcfamily;
5591 opcintype = cla_tup->opcintype;
5592 ReleaseSysCache(cla_ht);
5595 * Check it's a btree; currently this can never fail since no other
5596 * index AMs support unique indexes. If we ever did have other types
5597 * of unique indexes, we'd need a way to determine which operator
5598 * strategy number is equality. (Is it reasonable to insist that
5599 * every such index AM use btree's number for equality?)
5601 if (amid != BTREE_AM_OID)
5602 elog(ERROR, "only b-tree indexes are supported for foreign keys");
5603 eqstrategy = BTEqualStrategyNumber;
5606 * There had better be a primary equality operator for the index.
5607 * We'll use it for PK = PK comparisons.
5609 ppeqop = get_opfamily_member(opfamily, opcintype, opcintype,
5612 if (!OidIsValid(ppeqop))
5613 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
5614 eqstrategy, opcintype, opcintype, opfamily);
5617 * Are there equality operators that take exactly the FK type? Assume
5618 * we should look through any domain here.
5620 fktyped = getBaseType(fktype);
5622 pfeqop = get_opfamily_member(opfamily, opcintype, fktyped,
5624 if (OidIsValid(pfeqop))
5625 ffeqop = get_opfamily_member(opfamily, fktyped, fktyped,
5628 ffeqop = InvalidOid; /* keep compiler quiet */
5630 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
5633 * Otherwise, look for an implicit cast from the FK type to the
5634 * opcintype, and if found, use the primary equality operator.
5635 * This is a bit tricky because opcintype might be a polymorphic
5636 * type such as ANYARRAY or ANYENUM; so what we have to test is
5637 * whether the two actual column types can be concurrently cast to
5638 * that type. (Otherwise, we'd fail to reject combinations such
5639 * as int[] and point[].)
5641 Oid input_typeids[2];
5642 Oid target_typeids[2];
5644 input_typeids[0] = pktype;
5645 input_typeids[1] = fktype;
5646 target_typeids[0] = opcintype;
5647 target_typeids[1] = opcintype;
5648 if (can_coerce_type(2, input_typeids, target_typeids,
5650 pfeqop = ffeqop = ppeqop;
5653 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
5655 (errcode(ERRCODE_DATATYPE_MISMATCH),
5656 errmsg("foreign key constraint \"%s\" "
5657 "cannot be implemented",
5658 fkconstraint->conname),
5659 errdetail("Key columns \"%s\" and \"%s\" "
5660 "are of incompatible types: %s and %s.",
5661 strVal(list_nth(fkconstraint->fk_attrs, i)),
5662 strVal(list_nth(fkconstraint->pk_attrs, i)),
5663 format_type_be(fktype),
5664 format_type_be(pktype))));
5666 pfeqoperators[i] = pfeqop;
5667 ppeqoperators[i] = ppeqop;
5668 ffeqoperators[i] = ffeqop;
5672 * Record the FK constraint in pg_constraint.
5674 constrOid = CreateConstraintEntry(fkconstraint->conname,
5675 RelationGetNamespace(rel),
5677 fkconstraint->deferrable,
5678 fkconstraint->initdeferred,
5679 fkconstraint->initially_valid,
5680 RelationGetRelid(rel),
5683 InvalidOid, /* not a domain
5686 RelationGetRelid(pkrel),
5692 fkconstraint->fk_upd_action,
5693 fkconstraint->fk_del_action,
5694 fkconstraint->fk_matchtype,
5695 NULL, /* no exclusion constraint */
5696 NULL, /* no check constraint */
5703 * Create the triggers that will enforce the constraint.
5705 createForeignKeyTriggers(rel, fkconstraint, constrOid, indexOid);
5708 * Tell Phase 3 to check that the constraint is satisfied by existing rows
5709 * We can skip this during table creation or if requested explicitly by
5710 * specifying NOT VALID on an alter table statement.
5712 if (!fkconstraint->skip_validation)
5714 NewConstraint *newcon;
5716 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
5717 newcon->name = fkconstraint->conname;
5718 newcon->contype = CONSTR_FOREIGN;
5719 newcon->refrelid = RelationGetRelid(pkrel);
5720 newcon->refindid = indexOid;
5721 newcon->conid = constrOid;
5722 newcon->qual = (Node *) fkconstraint;
5724 tab->constraints = lappend(tab->constraints, newcon);
5728 * Close pk table, but keep lock until we've committed.
5730 heap_close(pkrel, NoLock);
5734 * ALTER TABLE VALIDATE CONSTRAINT
5737 ATExecValidateConstraint(Relation rel, const char *constrName)
5743 Form_pg_constraint con = NULL;
5746 conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
5749 * Find and check the target constraint
5752 Anum_pg_constraint_conrelid,
5753 BTEqualStrategyNumber, F_OIDEQ,
5754 ObjectIdGetDatum(RelationGetRelid(rel)));
5755 scan = systable_beginscan(conrel, ConstraintRelidIndexId,
5756 true, SnapshotNow, 1, &key);
5758 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5760 con = (Form_pg_constraint) GETSTRUCT(tuple);
5761 if (con->contype == CONSTRAINT_FOREIGN &&
5762 strcmp(NameStr(con->conname), constrName) == 0)
5771 (errcode(ERRCODE_UNDEFINED_OBJECT),
5772 errmsg("foreign key constraint \"%s\" of relation \"%s\" does not exist",
5773 constrName, RelationGetRelationName(rel))));
5775 if (!con->convalidated)
5777 Oid conid = HeapTupleGetOid(tuple);
5778 HeapTuple copyTuple = heap_copytuple(tuple);
5779 Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
5783 * Triggers are already in place on both tables, so a concurrent write
5784 * that alters the result here is not possible. Normally we can run a
5785 * query here to do the validation, which would only require
5786 * AccessShareLock. In some cases, it is possible that we might need
5787 * to fire triggers to perform the check, so we take a lock at
5788 * RowShareLock level just in case.
5790 refrel = heap_open(con->confrelid, RowShareLock);
5792 validateForeignKeyConstraint((char *) constrName, rel, refrel,
5797 * Now update the catalog, while we have the door open.
5799 copy_con->convalidated = true;
5800 simple_heap_update(conrel, ©Tuple->t_self, copyTuple);
5801 CatalogUpdateIndexes(conrel, copyTuple);
5802 heap_freetuple(copyTuple);
5804 heap_close(refrel, NoLock);
5807 systable_endscan(scan);
5809 heap_close(conrel, RowExclusiveLock);
5813 * transformColumnNameList - transform list of column names
5815 * Lookup each name and return its attnum and type OID
5818 transformColumnNameList(Oid relId, List *colList,
5819 int16 *attnums, Oid *atttypids)
5827 char *attname = strVal(lfirst(l));
5830 atttuple = SearchSysCacheAttName(relId, attname);
5831 if (!HeapTupleIsValid(atttuple))
5833 (errcode(ERRCODE_UNDEFINED_COLUMN),
5834 errmsg("column \"%s\" referenced in foreign key constraint does not exist",
5836 if (attnum >= INDEX_MAX_KEYS)
5838 (errcode(ERRCODE_TOO_MANY_COLUMNS),
5839 errmsg("cannot have more than %d keys in a foreign key",
5841 attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
5842 atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
5843 ReleaseSysCache(atttuple);
5851 * transformFkeyGetPrimaryKey -
5853 * Look up the names, attnums, and types of the primary key attributes
5854 * for the pkrel. Also return the index OID and index opclasses of the
5855 * index supporting the primary key.
5857 * All parameters except pkrel are output parameters. Also, the function
5858 * return value is the number of attributes in the primary key.
5860 * Used when the column list in the REFERENCES specification is omitted.
5863 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
5865 int16 *attnums, Oid *atttypids,
5869 ListCell *indexoidscan;
5870 HeapTuple indexTuple = NULL;
5871 Form_pg_index indexStruct = NULL;
5872 Datum indclassDatum;
5874 oidvector *indclass;
5878 * Get the list of index OIDs for the table from the relcache, and look up
5879 * each one in the pg_index syscache until we find one marked primary key
5880 * (hopefully there isn't more than one such).
5882 *indexOid = InvalidOid;
5884 indexoidlist = RelationGetIndexList(pkrel);
5886 foreach(indexoidscan, indexoidlist)
5888 Oid indexoid = lfirst_oid(indexoidscan);
5890 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
5891 if (!HeapTupleIsValid(indexTuple))
5892 elog(ERROR, "cache lookup failed for index %u", indexoid);
5893 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
5894 if (indexStruct->indisprimary)
5897 * Refuse to use a deferrable primary key. This is per SQL spec,
5898 * and there would be a lot of interesting semantic problems if we
5899 * tried to allow it.
5901 if (!indexStruct->indimmediate)
5903 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5904 errmsg("cannot use a deferrable primary key for referenced table \"%s\"",
5905 RelationGetRelationName(pkrel))));
5907 *indexOid = indexoid;
5910 ReleaseSysCache(indexTuple);
5913 list_free(indexoidlist);
5916 * Check that we found it
5918 if (!OidIsValid(*indexOid))
5920 (errcode(ERRCODE_UNDEFINED_OBJECT),
5921 errmsg("there is no primary key for referenced table \"%s\"",
5922 RelationGetRelationName(pkrel))));
5924 /* Must get indclass the hard way */
5925 indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
5926 Anum_pg_index_indclass, &isnull);
5928 indclass = (oidvector *) DatumGetPointer(indclassDatum);
5931 * Now build the list of PK attributes from the indkey definition (we
5932 * assume a primary key cannot have expressional elements)
5935 for (i = 0; i < indexStruct->indnatts; i++)
5937 int pkattno = indexStruct->indkey.values[i];
5939 attnums[i] = pkattno;
5940 atttypids[i] = attnumTypeId(pkrel, pkattno);
5941 opclasses[i] = indclass->values[i];
5942 *attnamelist = lappend(*attnamelist,
5943 makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
5946 ReleaseSysCache(indexTuple);
5952 * transformFkeyCheckAttrs -
5954 * Make sure that the attributes of a referenced table belong to a unique
5955 * (or primary key) constraint. Return the OID of the index supporting
5956 * the constraint, as well as the opclasses associated with the index
5960 transformFkeyCheckAttrs(Relation pkrel,
5961 int numattrs, int16 *attnums,
5962 Oid *opclasses) /* output parameter */
5964 Oid indexoid = InvalidOid;
5966 bool found_deferrable = false;
5968 ListCell *indexoidscan;
5971 * Get the list of index OIDs for the table from the relcache, and look up
5972 * each one in the pg_index syscache, and match unique indexes to the list
5973 * of attnums we are given.
5975 indexoidlist = RelationGetIndexList(pkrel);
5977 foreach(indexoidscan, indexoidlist)
5979 HeapTuple indexTuple;
5980 Form_pg_index indexStruct;
5984 indexoid = lfirst_oid(indexoidscan);
5985 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
5986 if (!HeapTupleIsValid(indexTuple))
5987 elog(ERROR, "cache lookup failed for index %u", indexoid);
5988 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
5991 * Must have the right number of columns; must be unique and not a
5992 * partial index; forget it if there are any expressions, too
5994 if (indexStruct->indnatts == numattrs &&
5995 indexStruct->indisunique &&
5996 heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
5997 heap_attisnull(indexTuple, Anum_pg_index_indexprs))
5999 /* Must get indclass the hard way */
6000 Datum indclassDatum;
6002 oidvector *indclass;
6004 indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
6005 Anum_pg_index_indclass, &isnull);
6007 indclass = (oidvector *) DatumGetPointer(indclassDatum);
6010 * The given attnum list may match the index columns in any order.
6011 * Check that each list is a subset of the other.
6013 for (i = 0; i < numattrs; i++)
6016 for (j = 0; j < numattrs; j++)
6018 if (attnums[i] == indexStruct->indkey.values[j])
6029 for (i = 0; i < numattrs; i++)
6032 for (j = 0; j < numattrs; j++)
6034 if (attnums[j] == indexStruct->indkey.values[i])
6036 opclasses[j] = indclass->values[i];
6047 * Refuse to use a deferrable unique/primary key. This is per SQL
6048 * spec, and there would be a lot of interesting semantic problems
6049 * if we tried to allow it.
6051 if (found && !indexStruct->indimmediate)
6054 * Remember that we found an otherwise matching index, so that
6055 * we can generate a more appropriate error message.
6057 found_deferrable = true;
6061 ReleaseSysCache(indexTuple);
6068 if (found_deferrable)
6070 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6071 errmsg("cannot use a deferrable unique constraint for referenced table \"%s\"",
6072 RelationGetRelationName(pkrel))));
6075 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
6076 errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
6077 RelationGetRelationName(pkrel))));
6080 list_free(indexoidlist);
6085 /* Permissions checks for ADD FOREIGN KEY */
6087 checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
6089 Oid roleid = GetUserId();
6090 AclResult aclresult;
6093 /* Okay if we have relation-level REFERENCES permission */
6094 aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid,
6096 if (aclresult == ACLCHECK_OK)
6098 /* Else we must have REFERENCES on each column */
6099 for (i = 0; i < natts; i++)
6101 aclresult = pg_attribute_aclcheck(RelationGetRelid(rel), attnums[i],
6102 roleid, ACL_REFERENCES);
6103 if (aclresult != ACLCHECK_OK)
6104 aclcheck_error(aclresult, ACL_KIND_CLASS,
6105 RelationGetRelationName(rel));
6110 * Scan the existing rows in a table to verify they meet a proposed FK
6113 * Caller must have opened and locked both relations appropriately.
6116 validateForeignKeyConstraint(char *conname,
6127 (errmsg("validating foreign key constraint \"%s\"", conname)));
6130 * Build a trigger call structure; we'll need it either way.
6132 MemSet(&trig, 0, sizeof(trig));
6133 trig.tgoid = InvalidOid;
6134 trig.tgname = conname;
6135 trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN;
6136 trig.tgisinternal = TRUE;
6137 trig.tgconstrrelid = RelationGetRelid(pkrel);
6138 trig.tgconstrindid = pkindOid;
6139 trig.tgconstraint = constraintOid;
6140 trig.tgdeferrable = FALSE;
6141 trig.tginitdeferred = FALSE;
6142 /* we needn't fill in tgargs or tgqual */
6145 * See if we can do it with a single LEFT JOIN query. A FALSE result
6146 * indicates we must proceed with the fire-the-trigger method.
6148 if (RI_Initial_Check(&trig, rel, pkrel))
6152 * Scan through each tuple, calling RI_FKey_check_ins (insert trigger) as
6153 * if that tuple had just been inserted. If any of those fail, it should
6154 * ereport(ERROR) and that's that.
6156 scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
6158 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
6160 FunctionCallInfoData fcinfo;
6161 TriggerData trigdata;
6164 * Make a call to the trigger function
6166 * No parameters are passed, but we do set a context
6168 MemSet(&fcinfo, 0, sizeof(fcinfo));
6171 * We assume RI_FKey_check_ins won't look at flinfo...
6173 trigdata.type = T_TriggerData;
6174 trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
6175 trigdata.tg_relation = rel;
6176 trigdata.tg_trigtuple = tuple;
6177 trigdata.tg_newtuple = NULL;
6178 trigdata.tg_trigger = &trig;
6179 trigdata.tg_trigtuplebuf = scan->rs_cbuf;
6180 trigdata.tg_newtuplebuf = InvalidBuffer;
6182 fcinfo.context = (Node *) &trigdata;
6184 RI_FKey_check_ins(&fcinfo);
6191 CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint,
6192 Oid constraintOid, Oid indexOid, bool on_insert)
6194 CreateTrigStmt *fk_trigger;
6196 fk_trigger = makeNode(CreateTrigStmt);
6197 fk_trigger->trigname = "RI_ConstraintTrigger";
6198 fk_trigger->relation = myRel;
6199 fk_trigger->row = true;
6200 fk_trigger->timing = TRIGGER_TYPE_AFTER;
6202 /* Either ON INSERT or ON UPDATE */
6205 fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
6206 fk_trigger->events = TRIGGER_TYPE_INSERT;
6210 fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
6211 fk_trigger->events = TRIGGER_TYPE_UPDATE;
6214 fk_trigger->columns = NIL;
6215 fk_trigger->whenClause = NULL;
6216 fk_trigger->isconstraint = true;
6217 fk_trigger->deferrable = fkconstraint->deferrable;
6218 fk_trigger->initdeferred = fkconstraint->initdeferred;
6219 fk_trigger->constrrel = fkconstraint->pktable;
6220 fk_trigger->args = NIL;
6222 (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6224 /* Make changes-so-far visible */
6225 CommandCounterIncrement();
6229 * Create the triggers that implement an FK constraint.
6232 createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
6233 Oid constraintOid, Oid indexOid)
6236 CreateTrigStmt *fk_trigger;
6239 * Reconstruct a RangeVar for my relation (not passed in, unfortunately).
6241 myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
6242 pstrdup(RelationGetRelationName(rel)),
6245 /* Make changes-so-far visible */
6246 CommandCounterIncrement();
6249 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK
6250 * action for both INSERTs and UPDATEs on the referencing table.
6252 CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, true);
6253 CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, false);
6256 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
6257 * DELETE action on the referenced table.
6259 fk_trigger = makeNode(CreateTrigStmt);
6260 fk_trigger->trigname = "RI_ConstraintTrigger";
6261 fk_trigger->relation = fkconstraint->pktable;
6262 fk_trigger->row = true;
6263 fk_trigger->timing = TRIGGER_TYPE_AFTER;
6264 fk_trigger->events = TRIGGER_TYPE_DELETE;
6265 fk_trigger->columns = NIL;
6266 fk_trigger->whenClause = NULL;
6267 fk_trigger->isconstraint = true;
6268 fk_trigger->constrrel = myRel;
6269 switch (fkconstraint->fk_del_action)
6271 case FKCONSTR_ACTION_NOACTION:
6272 fk_trigger->deferrable = fkconstraint->deferrable;
6273 fk_trigger->initdeferred = fkconstraint->initdeferred;
6274 fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
6276 case FKCONSTR_ACTION_RESTRICT:
6277 fk_trigger->deferrable = false;
6278 fk_trigger->initdeferred = false;
6279 fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
6281 case FKCONSTR_ACTION_CASCADE:
6282 fk_trigger->deferrable = false;
6283 fk_trigger->initdeferred = false;
6284 fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
6286 case FKCONSTR_ACTION_SETNULL:
6287 fk_trigger->deferrable = false;
6288 fk_trigger->initdeferred = false;
6289 fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
6291 case FKCONSTR_ACTION_SETDEFAULT:
6292 fk_trigger->deferrable = false;
6293 fk_trigger->initdeferred = false;
6294 fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
6297 elog(ERROR, "unrecognized FK action type: %d",
6298 (int) fkconstraint->fk_del_action);
6301 fk_trigger->args = NIL;
6303 (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6305 /* Make changes-so-far visible */
6306 CommandCounterIncrement();
6309 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
6310 * UPDATE action on the referenced table.
6312 fk_trigger = makeNode(CreateTrigStmt);
6313 fk_trigger->trigname = "RI_ConstraintTrigger";
6314 fk_trigger->relation = fkconstraint->pktable;
6315 fk_trigger->row = true;
6316 fk_trigger->timing = TRIGGER_TYPE_AFTER;
6317 fk_trigger->events = TRIGGER_TYPE_UPDATE;
6318 fk_trigger->columns = NIL;
6319 fk_trigger->whenClause = NULL;
6320 fk_trigger->isconstraint = true;
6321 fk_trigger->constrrel = myRel;
6322 switch (fkconstraint->fk_upd_action)
6324 case FKCONSTR_ACTION_NOACTION:
6325 fk_trigger->deferrable = fkconstraint->deferrable;
6326 fk_trigger->initdeferred = fkconstraint->initdeferred;
6327 fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
6329 case FKCONSTR_ACTION_RESTRICT:
6330 fk_trigger->deferrable = false;
6331 fk_trigger->initdeferred = false;
6332 fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
6334 case FKCONSTR_ACTION_CASCADE:
6335 fk_trigger->deferrable = false;
6336 fk_trigger->initdeferred = false;
6337 fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
6339 case FKCONSTR_ACTION_SETNULL:
6340 fk_trigger->deferrable = false;
6341 fk_trigger->initdeferred = false;
6342 fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
6344 case FKCONSTR_ACTION_SETDEFAULT:
6345 fk_trigger->deferrable = false;
6346 fk_trigger->initdeferred = false;
6347 fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
6350 elog(ERROR, "unrecognized FK action type: %d",
6351 (int) fkconstraint->fk_upd_action);
6354 fk_trigger->args = NIL;
6356 (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6360 * ALTER TABLE DROP CONSTRAINT
6362 * Like DROP COLUMN, we can't use the normal ALTER TABLE recursion mechanism.
6365 ATExecDropConstraint(Relation rel, const char *constrName,
6366 DropBehavior behavior,
6367 bool recurse, bool recursing,
6368 bool missing_ok, LOCKMODE lockmode)
6373 Form_pg_constraint con;
6378 bool is_check_constraint = false;
6380 /* At top level, permission check was done in ATPrepCmd, else do it */
6382 ATSimplePermissions(rel, ATT_TABLE);
6384 conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
6387 * Find and drop the target constraint
6390 Anum_pg_constraint_conrelid,
6391 BTEqualStrategyNumber, F_OIDEQ,
6392 ObjectIdGetDatum(RelationGetRelid(rel)));
6393 scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6394 true, SnapshotNow, 1, &key);
6396 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
6398 ObjectAddress conobj;
6400 con = (Form_pg_constraint) GETSTRUCT(tuple);
6402 if (strcmp(NameStr(con->conname), constrName) != 0)
6405 /* Don't drop inherited constraints */
6406 if (con->coninhcount > 0 && !recursing)
6408 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6409 errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
6410 constrName, RelationGetRelationName(rel))));
6412 /* Right now only CHECK constraints can be inherited */
6413 if (con->contype == CONSTRAINT_CHECK)
6414 is_check_constraint = true;
6417 * Perform the actual constraint deletion
6419 conobj.classId = ConstraintRelationId;
6420 conobj.objectId = HeapTupleGetOid(tuple);
6421 conobj.objectSubId = 0;
6423 performDeletion(&conobj, behavior);
6428 systable_endscan(scan);
6435 (errcode(ERRCODE_UNDEFINED_OBJECT),
6436 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6437 constrName, RelationGetRelationName(rel))));
6442 (errmsg("constraint \"%s\" of relation \"%s\" does not exist, skipping",
6443 constrName, RelationGetRelationName(rel))));
6444 heap_close(conrel, RowExclusiveLock);
6450 * Propagate to children as appropriate. Unlike most other ALTER
6451 * routines, we have to do this one level of recursion at a time; we can't
6452 * use find_all_inheritors to do it in one pass.
6454 if (is_check_constraint)
6455 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
6459 foreach(child, children)
6461 Oid childrelid = lfirst_oid(child);
6464 /* find_inheritance_children already got lock */
6465 childrel = heap_open(childrelid, NoLock);
6466 CheckTableNotInUse(childrel, "ALTER TABLE");
6469 Anum_pg_constraint_conrelid,
6470 BTEqualStrategyNumber, F_OIDEQ,
6471 ObjectIdGetDatum(childrelid));
6472 scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6473 true, SnapshotNow, 1, &key);
6477 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
6479 HeapTuple copy_tuple;
6481 con = (Form_pg_constraint) GETSTRUCT(tuple);
6483 /* Right now only CHECK constraints can be inherited */
6484 if (con->contype != CONSTRAINT_CHECK)
6487 if (strcmp(NameStr(con->conname), constrName) != 0)
6492 if (con->coninhcount <= 0) /* shouldn't happen */
6493 elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
6494 childrelid, constrName);
6496 copy_tuple = heap_copytuple(tuple);
6497 con = (Form_pg_constraint) GETSTRUCT(copy_tuple);
6502 * If the child constraint has other definition sources, just
6503 * decrement its inheritance count; if not, recurse to delete
6506 if (con->coninhcount == 1 && !con->conislocal)
6508 /* Time to delete this child constraint, too */
6509 ATExecDropConstraint(childrel, constrName, behavior,
6515 /* Child constraint must survive my deletion */
6517 simple_heap_update(conrel, ©_tuple->t_self, copy_tuple);
6518 CatalogUpdateIndexes(conrel, copy_tuple);
6520 /* Make update visible */
6521 CommandCounterIncrement();
6527 * If we were told to drop ONLY in this table (no recursion),
6528 * we need to mark the inheritors' constraints as locally
6529 * defined rather than inherited.
6532 con->conislocal = true;
6534 simple_heap_update(conrel, ©_tuple->t_self, copy_tuple);
6535 CatalogUpdateIndexes(conrel, copy_tuple);
6537 /* Make update visible */
6538 CommandCounterIncrement();
6541 heap_freetuple(copy_tuple);
6544 systable_endscan(scan);
6548 (errcode(ERRCODE_UNDEFINED_OBJECT),
6549 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6551 RelationGetRelationName(childrel))));
6553 heap_close(childrel, NoLock);
6556 heap_close(conrel, RowExclusiveLock);
6563 ATPrepAlterColumnType(List **wqueue,
6564 AlteredTableInfo *tab, Relation rel,
6565 bool recurse, bool recursing,
6566 AlterTableCmd *cmd, LOCKMODE lockmode)
6568 char *colName = cmd->name;
6569 ColumnDef *def = (ColumnDef *) cmd->def;
6570 TypeName *typeName = def->typeName;
6571 Node *transform = def->raw_default;
6573 Form_pg_attribute attTup;
6578 NewColumnValue *newval;
6579 ParseState *pstate = make_parsestate(NULL);
6581 if (rel->rd_rel->reloftype && !recursing)
6583 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6584 errmsg("cannot alter column type of typed table")));
6586 /* lookup the attribute so we can check inheritance status */
6587 tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
6588 if (!HeapTupleIsValid(tuple))
6590 (errcode(ERRCODE_UNDEFINED_COLUMN),
6591 errmsg("column \"%s\" of relation \"%s\" does not exist",
6592 colName, RelationGetRelationName(rel))));
6593 attTup = (Form_pg_attribute) GETSTRUCT(tuple);
6594 attnum = attTup->attnum;
6596 /* Can't alter a system attribute */
6599 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6600 errmsg("cannot alter system column \"%s\"",
6603 /* Don't alter inherited columns */
6604 if (attTup->attinhcount > 0 && !recursing)
6606 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6607 errmsg("cannot alter inherited column \"%s\"",
6610 /* Look up the target type */
6611 typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
6613 /* And the collation */
6614 targetcollid = GetColumnDefCollation(NULL, def, targettype);
6616 /* make sure datatype is legal for a column */
6617 CheckAttributeType(colName, targettype, targetcollid,
6618 list_make1_oid(rel->rd_rel->reltype),
6621 if (tab->relkind == RELKIND_RELATION)
6624 * Set up an expression to transform the old data value to the new
6625 * type. If a USING option was given, transform and use that
6626 * expression, else just take the old value and try to coerce it. We
6627 * do this first so that type incompatibility can be detected before
6628 * we waste effort, and because we need the expression to be parsed
6629 * against the original table rowtype.
6635 /* Expression must be able to access vars of old table */
6636 rte = addRangeTableEntryForRelation(pstate,
6641 addRTEtoQuery(pstate, rte, false, true, true);
6643 transform = transformExpr(pstate, transform);
6645 /* It can't return a set */
6646 if (expression_returns_set(transform))
6648 (errcode(ERRCODE_DATATYPE_MISMATCH),
6649 errmsg("transform expression must not return a set")));
6651 /* No subplans or aggregates, either... */
6652 if (pstate->p_hasSubLinks)
6654 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6655 errmsg("cannot use subquery in transform expression")));
6656 if (pstate->p_hasAggs)
6658 (errcode(ERRCODE_GROUPING_ERROR),
6659 errmsg("cannot use aggregate function in transform expression")));
6660 if (pstate->p_hasWindowFuncs)
6662 (errcode(ERRCODE_WINDOWING_ERROR),
6663 errmsg("cannot use window function in transform expression")));
6667 transform = (Node *) makeVar(1, attnum,
6668 attTup->atttypid, attTup->atttypmod,
6669 attTup->attcollation,
6673 transform = coerce_to_target_type(pstate,
6674 transform, exprType(transform),
6675 targettype, targettypmod,
6676 COERCION_ASSIGNMENT,
6677 COERCE_IMPLICIT_CAST,
6679 if (transform == NULL)
6681 (errcode(ERRCODE_DATATYPE_MISMATCH),
6682 errmsg("column \"%s\" cannot be cast to type %s",
6683 colName, format_type_be(targettype))));
6685 /* Fix collations after all else */
6686 assign_expr_collations(pstate, transform);
6689 * Add a work queue item to make ATRewriteTable update the column
6692 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
6693 newval->attnum = attnum;
6694 newval->expr = (Expr *) transform;
6696 tab->newvals = lappend(tab->newvals, newval);
6697 if (ATColumnChangeRequiresRewrite(transform, attnum))
6698 tab->rewrite = true;
6702 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6703 errmsg("ALTER TYPE USING is only supported on plain tables")));
6705 if (tab->relkind == RELKIND_COMPOSITE_TYPE ||
6706 tab->relkind == RELKIND_FOREIGN_TABLE)
6709 * For composite types, do this check now. Tables will check it later
6710 * when the table is being rewritten.
6712 find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
6715 ReleaseSysCache(tuple);
6718 * The recursion case is handled by ATSimpleRecursion. However, if we are
6719 * told not to recurse, there had better not be any child tables; else the
6720 * alter would put them out of step.
6723 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
6724 else if (!recursing &&
6725 find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
6727 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6728 errmsg("type of inherited column \"%s\" must be changed in child tables too",
6731 if (tab->relkind == RELKIND_COMPOSITE_TYPE)
6732 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
6736 * When the data type of a column is changed, a rewrite might not be required
6737 * if the new type is sufficiently identical to the old one, and the USING
6738 * clause isn't trying to insert some other value. It's safe to skip the
6739 * rewrite if the old type is binary coercible to the new type, or if the
6740 * new type is an unconstrained domain over the old type. In the case of a
6741 * constrained domain, we could get by with scanning the table and checking
6742 * the constraint rather than actually rewriting it, but we don't currently
6746 ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
6748 Assert(expr != NULL);
6752 /* only one varno, so no need to check that */
6753 if (IsA(expr, Var) &&((Var *) expr)->varattno == varattno)
6755 else if (IsA(expr, RelabelType))
6756 expr = (Node *) ((RelabelType *) expr)->arg;
6757 else if (IsA(expr, CoerceToDomain))
6759 CoerceToDomain *d = (CoerceToDomain *) expr;
6761 if (GetDomainConstraints(d->resulttype) != NIL)
6763 expr = (Node *) d->arg;
6771 ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
6772 AlterTableCmd *cmd, LOCKMODE lockmode)
6774 char *colName = cmd->name;
6775 ColumnDef *def = (ColumnDef *) cmd->def;
6776 TypeName *typeName = def->typeName;
6778 Form_pg_attribute attTup;
6780 HeapTuple typeTuple;
6786 Relation attrelation;
6792 attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
6794 /* Look up the target column */
6795 heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
6796 if (!HeapTupleIsValid(heapTup)) /* shouldn't happen */
6798 (errcode(ERRCODE_UNDEFINED_COLUMN),
6799 errmsg("column \"%s\" of relation \"%s\" does not exist",
6800 colName, RelationGetRelationName(rel))));
6801 attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
6802 attnum = attTup->attnum;
6804 /* Check for multiple ALTER TYPE on same column --- can't cope */
6805 if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
6806 attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
6808 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6809 errmsg("cannot alter type of column \"%s\" twice",
6812 /* Look up the target type (should not fail, since prep found it) */
6813 typeTuple = typenameType(NULL, typeName, &targettypmod);
6814 tform = (Form_pg_type) GETSTRUCT(typeTuple);
6815 targettype = HeapTupleGetOid(typeTuple);
6816 /* And the collation */
6817 targetcollid = GetColumnDefCollation(NULL, def, targettype);
6820 * If there is a default expression for the column, get it and ensure we
6821 * can coerce it to the new datatype. (We must do this before changing
6822 * the column type, because build_column_default itself will try to
6823 * coerce, and will not issue the error message we want if it fails.)
6825 * We remove any implicit coercion steps at the top level of the old
6826 * default expression; this has been agreed to satisfy the principle of
6827 * least surprise. (The conversion to the new column type should act like
6828 * it started from what the user sees as the stored expression, and the
6829 * implicit coercions aren't going to be shown.)
6831 if (attTup->atthasdef)
6833 defaultexpr = build_column_default(rel, attnum);
6834 Assert(defaultexpr);
6835 defaultexpr = strip_implicit_coercions(defaultexpr);
6836 defaultexpr = coerce_to_target_type(NULL, /* no UNKNOWN params */
6837 defaultexpr, exprType(defaultexpr),
6838 targettype, targettypmod,
6839 COERCION_ASSIGNMENT,
6840 COERCE_IMPLICIT_CAST,
6842 if (defaultexpr == NULL)
6844 (errcode(ERRCODE_DATATYPE_MISMATCH),
6845 errmsg("default for column \"%s\" cannot be cast to type %s",
6846 colName, format_type_be(targettype))));
6852 * Find everything that depends on the column (constraints, indexes, etc),
6853 * and record enough information to let us recreate the objects.
6855 * The actual recreation does not happen here, but only after we have
6856 * performed all the individual ALTER TYPE operations. We have to save
6857 * the info before executing ALTER TYPE, though, else the deparser will
6860 * There could be multiple entries for the same object, so we must check
6861 * to ensure we process each one only once. Note: we assume that an index
6862 * that implements a constraint will not show a direct dependency on the
6865 depRel = heap_open(DependRelationId, RowExclusiveLock);
6867 ScanKeyInit(&key[0],
6868 Anum_pg_depend_refclassid,
6869 BTEqualStrategyNumber, F_OIDEQ,
6870 ObjectIdGetDatum(RelationRelationId));
6871 ScanKeyInit(&key[1],
6872 Anum_pg_depend_refobjid,
6873 BTEqualStrategyNumber, F_OIDEQ,
6874 ObjectIdGetDatum(RelationGetRelid(rel)));
6875 ScanKeyInit(&key[2],
6876 Anum_pg_depend_refobjsubid,
6877 BTEqualStrategyNumber, F_INT4EQ,
6878 Int32GetDatum((int32) attnum));
6880 scan = systable_beginscan(depRel, DependReferenceIndexId, true,
6881 SnapshotNow, 3, key);
6883 while (HeapTupleIsValid(depTup = systable_getnext(scan)))
6885 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
6886 ObjectAddress foundObject;
6888 /* We don't expect any PIN dependencies on columns */
6889 if (foundDep->deptype == DEPENDENCY_PIN)
6890 elog(ERROR, "cannot alter type of a pinned column");
6892 foundObject.classId = foundDep->classid;
6893 foundObject.objectId = foundDep->objid;
6894 foundObject.objectSubId = foundDep->objsubid;
6896 switch (getObjectClass(&foundObject))
6900 char relKind = get_rel_relkind(foundObject.objectId);
6902 if (relKind == RELKIND_INDEX)
6904 Assert(foundObject.objectSubId == 0);
6905 if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
6907 tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
6908 foundObject.objectId);
6909 tab->changedIndexDefs = lappend(tab->changedIndexDefs,
6910 pg_get_indexdef_string(foundObject.objectId));
6913 else if (relKind == RELKIND_SEQUENCE)
6916 * This must be a SERIAL column's sequence. We need
6917 * not do anything to it.
6919 Assert(foundObject.objectSubId == 0);
6923 /* Not expecting any other direct dependencies... */
6924 elog(ERROR, "unexpected object depending on column: %s",
6925 getObjectDescription(&foundObject));
6930 case OCLASS_CONSTRAINT:
6931 Assert(foundObject.objectSubId == 0);
6932 if (!list_member_oid(tab->changedConstraintOids,
6933 foundObject.objectId))
6935 char *defstring = pg_get_constraintdef_string(foundObject.objectId);
6938 * Put NORMAL dependencies at the front of the list and
6939 * AUTO dependencies at the back. This makes sure that
6940 * foreign-key constraints depending on this column will
6941 * be dropped before unique or primary-key constraints of
6942 * the column; which we must have because the FK
6943 * constraints depend on the indexes belonging to the
6944 * unique constraints.
6946 if (foundDep->deptype == DEPENDENCY_NORMAL)
6948 tab->changedConstraintOids =
6949 lcons_oid(foundObject.objectId,
6950 tab->changedConstraintOids);
6951 tab->changedConstraintDefs =
6953 tab->changedConstraintDefs);
6957 tab->changedConstraintOids =
6958 lappend_oid(tab->changedConstraintOids,
6959 foundObject.objectId);
6960 tab->changedConstraintDefs =
6961 lappend(tab->changedConstraintDefs,
6967 case OCLASS_REWRITE:
6968 /* XXX someday see if we can cope with revising views */
6970 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6971 errmsg("cannot alter type of a column used by a view or rule"),
6972 errdetail("%s depends on column \"%s\"",
6973 getObjectDescription(&foundObject),
6977 case OCLASS_TRIGGER:
6980 * A trigger can depend on a column because the column is
6981 * specified as an update target, or because the column is
6982 * used in the trigger's WHEN condition. The first case would
6983 * not require any extra work, but the second case would
6984 * require updating the WHEN expression, which will take a
6985 * significant amount of new code. Since we can't easily tell
6986 * which case applies, we punt for both. FIXME someday.
6989 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6990 errmsg("cannot alter type of a column used in a trigger definition"),
6991 errdetail("%s depends on column \"%s\"",
6992 getObjectDescription(&foundObject),
6996 case OCLASS_DEFAULT:
6999 * Ignore the column's default expression, since we will fix
7002 Assert(defaultexpr);
7008 case OCLASS_COLLATION:
7009 case OCLASS_CONVERSION:
7010 case OCLASS_LANGUAGE:
7011 case OCLASS_LARGEOBJECT:
7012 case OCLASS_OPERATOR:
7013 case OCLASS_OPCLASS:
7014 case OCLASS_OPFAMILY:
7018 case OCLASS_TSPARSER:
7020 case OCLASS_TSTEMPLATE:
7021 case OCLASS_TSCONFIG:
7023 case OCLASS_DATABASE:
7024 case OCLASS_TBLSPACE:
7026 case OCLASS_FOREIGN_SERVER:
7027 case OCLASS_USER_MAPPING:
7029 case OCLASS_EXTENSION:
7032 * We don't expect any of these sorts of objects to depend on
7035 elog(ERROR, "unexpected object depending on column: %s",
7036 getObjectDescription(&foundObject));
7040 elog(ERROR, "unrecognized object class: %u",
7041 foundObject.classId);
7045 systable_endscan(scan);
7048 * Now scan for dependencies of this column on other things. The only
7049 * thing we should find is the dependency on the column datatype, which we
7050 * want to remove, and possibly a collation dependency.
7052 ScanKeyInit(&key[0],
7053 Anum_pg_depend_classid,
7054 BTEqualStrategyNumber, F_OIDEQ,
7055 ObjectIdGetDatum(RelationRelationId));
7056 ScanKeyInit(&key[1],
7057 Anum_pg_depend_objid,
7058 BTEqualStrategyNumber, F_OIDEQ,
7059 ObjectIdGetDatum(RelationGetRelid(rel)));
7060 ScanKeyInit(&key[2],
7061 Anum_pg_depend_objsubid,
7062 BTEqualStrategyNumber, F_INT4EQ,
7063 Int32GetDatum((int32) attnum));
7065 scan = systable_beginscan(depRel, DependDependerIndexId, true,
7066 SnapshotNow, 3, key);
7068 while (HeapTupleIsValid(depTup = systable_getnext(scan)))
7070 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
7072 if (foundDep->deptype != DEPENDENCY_NORMAL)
7073 elog(ERROR, "found unexpected dependency type '%c'",
7075 if (!(foundDep->refclassid == TypeRelationId &&
7076 foundDep->refobjid == attTup->atttypid) &&
7077 !(foundDep->refclassid == CollationRelationId &&
7078 foundDep->refobjid == attTup->attcollation))
7079 elog(ERROR, "found unexpected dependency for column");
7081 simple_heap_delete(depRel, &depTup->t_self);
7084 systable_endscan(scan);
7086 heap_close(depRel, RowExclusiveLock);
7089 * Here we go --- change the recorded column type and collation. (Note
7090 * heapTup is a copy of the syscache entry, so okay to scribble on.)
7092 attTup->atttypid = targettype;
7093 attTup->atttypmod = targettypmod;
7094 attTup->attcollation = targetcollid;
7095 attTup->attndims = list_length(typeName->arrayBounds);
7096 attTup->attlen = tform->typlen;
7097 attTup->attbyval = tform->typbyval;
7098 attTup->attalign = tform->typalign;
7099 attTup->attstorage = tform->typstorage;
7101 ReleaseSysCache(typeTuple);
7103 simple_heap_update(attrelation, &heapTup->t_self, heapTup);
7105 /* keep system catalog indexes current */
7106 CatalogUpdateIndexes(attrelation, heapTup);
7108 heap_close(attrelation, RowExclusiveLock);
7110 /* Install dependencies on new datatype and collation */
7111 add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
7112 add_column_collation_dependency(RelationGetRelid(rel), attnum, targetcollid);
7115 * Drop any pg_statistic entry for the column, since it's now wrong type
7117 RemoveStatistics(RelationGetRelid(rel), attnum);
7120 * Update the default, if present, by brute force --- remove and re-add
7121 * the default. Probably unsafe to take shortcuts, since the new version
7122 * may well have additional dependencies. (It's okay to do this now,
7123 * rather than after other ALTER TYPE commands, since the default won't
7124 * depend on other column types.)
7128 /* Must make new row visible since it will be updated again */
7129 CommandCounterIncrement();
7132 * We use RESTRICT here for safety, but at present we do not expect
7133 * anything to depend on the default.
7135 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
7137 StoreAttrDefault(rel, attnum, defaultexpr);
7141 heap_freetuple(heapTup);
7145 * Cleanup after we've finished all the ALTER TYPE operations for a
7146 * particular relation. We have to drop and recreate all the indexes
7147 * and constraints that depend on the altered columns.
7150 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
7156 * Re-parse the index and constraint definitions, and attach them to the
7157 * appropriate work queue entries. We do this before dropping because in
7158 * the case of a FOREIGN KEY constraint, we might not yet have exclusive
7159 * lock on the table the constraint is attached to, and we need to get
7160 * that before dropping. It's safe because the parser won't actually look
7161 * at the catalogs to detect the existing entry.
7163 foreach(l, tab->changedIndexDefs)
7164 ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
7165 foreach(l, tab->changedConstraintDefs)
7166 ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
7169 * Now we can drop the existing constraints and indexes --- constraints
7170 * first, since some of them might depend on the indexes. In fact, we
7171 * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
7172 * we already ordered the constraint list to ensure that would happen. It
7173 * should be okay to use DROP_RESTRICT here, since nothing else should be
7174 * depending on these objects.
7176 foreach(l, tab->changedConstraintOids)
7178 obj.classId = ConstraintRelationId;
7179 obj.objectId = lfirst_oid(l);
7180 obj.objectSubId = 0;
7181 performDeletion(&obj, DROP_RESTRICT);
7184 foreach(l, tab->changedIndexOids)
7186 obj.classId = RelationRelationId;
7187 obj.objectId = lfirst_oid(l);
7188 obj.objectSubId = 0;
7189 performDeletion(&obj, DROP_RESTRICT);
7193 * The objects will get recreated during subsequent passes over the work
7199 ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
7201 List *raw_parsetree_list;
7202 List *querytree_list;
7203 ListCell *list_item;
7206 * We expect that we will get only ALTER TABLE and CREATE INDEX
7207 * statements. Hence, there is no need to pass them through
7208 * parse_analyze() or the rewriter, but instead we need to pass them
7209 * through parse_utilcmd.c to make them ready for execution.
7211 raw_parsetree_list = raw_parser(cmd);
7212 querytree_list = NIL;
7213 foreach(list_item, raw_parsetree_list)
7215 Node *stmt = (Node *) lfirst(list_item);
7217 if (IsA(stmt, IndexStmt))
7218 querytree_list = lappend(querytree_list,
7219 transformIndexStmt((IndexStmt *) stmt,
7221 else if (IsA(stmt, AlterTableStmt))
7222 querytree_list = list_concat(querytree_list,
7223 transformAlterTableStmt((AlterTableStmt *) stmt,
7226 querytree_list = lappend(querytree_list, stmt);
7230 * Attach each generated command to the proper place in the work queue.
7231 * Note this could result in creation of entirely new work-queue entries.
7233 foreach(list_item, querytree_list)
7235 Node *stm = (Node *) lfirst(list_item);
7237 AlteredTableInfo *tab;
7239 switch (nodeTag(stm))
7243 IndexStmt *stmt = (IndexStmt *) stm;
7244 AlterTableCmd *newcmd;
7246 rel = relation_openrv(stmt->relation, lockmode);
7247 tab = ATGetQueueEntry(wqueue, rel);
7248 newcmd = makeNode(AlterTableCmd);
7249 newcmd->subtype = AT_ReAddIndex;
7250 newcmd->def = (Node *) stmt;
7251 tab->subcmds[AT_PASS_OLD_INDEX] =
7252 lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
7253 relation_close(rel, NoLock);
7256 case T_AlterTableStmt:
7258 AlterTableStmt *stmt = (AlterTableStmt *) stm;
7261 rel = relation_openrv(stmt->relation, lockmode);
7262 tab = ATGetQueueEntry(wqueue, rel);
7263 foreach(lcmd, stmt->cmds)
7265 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
7267 switch (cmd->subtype)
7270 cmd->subtype = AT_ReAddIndex;
7271 tab->subcmds[AT_PASS_OLD_INDEX] =
7272 lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
7274 case AT_AddConstraint:
7275 tab->subcmds[AT_PASS_OLD_CONSTR] =
7276 lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
7279 elog(ERROR, "unexpected statement type: %d",
7280 (int) cmd->subtype);
7283 relation_close(rel, NoLock);
7287 elog(ERROR, "unexpected statement type: %d",
7288 (int) nodeTag(stm));
7297 * recursing is true if we are recursing from a table to its indexes,
7298 * sequences, or toast table. We don't allow the ownership of those things to
7299 * be changed separately from the parent table. Also, we can skip permission
7300 * checks (this is necessary not just an optimization, else we'd fail to
7301 * handle toast tables properly).
7303 * recursing is also true if ALTER TYPE OWNER is calling us to fix up a
7304 * free-standing composite type.
7307 ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
7309 Relation target_rel;
7312 Form_pg_class tuple_class;
7315 * Get exclusive lock till end of transaction on the target table. Use
7316 * relation_open so that we can work on indexes and sequences.
7318 target_rel = relation_open(relationOid, lockmode);
7320 /* Get its pg_class tuple, too */
7321 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
7323 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationOid));
7324 if (!HeapTupleIsValid(tuple))
7325 elog(ERROR, "cache lookup failed for relation %u", relationOid);
7326 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
7328 /* Can we change the ownership of this tuple? */
7329 switch (tuple_class->relkind)
7331 case RELKIND_RELATION:
7333 case RELKIND_FOREIGN_TABLE:
7334 /* ok to change owner */
7340 * Because ALTER INDEX OWNER used to be allowed, and in fact
7341 * is generated by old versions of pg_dump, we give a warning
7342 * and do nothing rather than erroring out. Also, to avoid
7343 * unnecessary chatter while restoring those old dumps, say
7344 * nothing at all if the command would be a no-op anyway.
7346 if (tuple_class->relowner != newOwnerId)
7348 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7349 errmsg("cannot change owner of index \"%s\"",
7350 NameStr(tuple_class->relname)),
7351 errhint("Change the ownership of the index's table, instead.")));
7352 /* quick hack to exit via the no-op path */
7353 newOwnerId = tuple_class->relowner;
7356 case RELKIND_SEQUENCE:
7358 tuple_class->relowner != newOwnerId)
7360 /* if it's an owned sequence, disallow changing it by itself */
7364 if (sequenceIsOwned(relationOid, &tableId, &colId))
7366 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7367 errmsg("cannot change owner of sequence \"%s\"",
7368 NameStr(tuple_class->relname)),
7369 errdetail("Sequence \"%s\" is linked to table \"%s\".",
7370 NameStr(tuple_class->relname),
7371 get_rel_name(tableId))));
7374 case RELKIND_COMPOSITE_TYPE:
7378 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7379 errmsg("\"%s\" is a composite type",
7380 NameStr(tuple_class->relname)),
7381 errhint("Use ALTER TYPE instead.")));
7383 case RELKIND_TOASTVALUE:
7389 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7390 errmsg("\"%s\" is not a table, view, sequence, or foreign tabl, or foreign tablee",
7391 NameStr(tuple_class->relname))));
7395 * If the new owner is the same as the existing owner, consider the
7396 * command to have succeeded. This is for dump restoration purposes.
7398 if (tuple_class->relowner != newOwnerId)
7400 Datum repl_val[Natts_pg_class];
7401 bool repl_null[Natts_pg_class];
7402 bool repl_repl[Natts_pg_class];
7408 /* skip permission checks when recursing to index or toast table */
7411 /* Superusers can always do it */
7414 Oid namespaceOid = tuple_class->relnamespace;
7415 AclResult aclresult;
7417 /* Otherwise, must be owner of the existing object */
7418 if (!pg_class_ownercheck(relationOid, GetUserId()))
7419 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
7420 RelationGetRelationName(target_rel));
7422 /* Must be able to become new owner */
7423 check_is_member_of_role(GetUserId(), newOwnerId);
7425 /* New owner must have CREATE privilege on namespace */
7426 aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
7428 if (aclresult != ACLCHECK_OK)
7429 aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
7430 get_namespace_name(namespaceOid));
7434 memset(repl_null, false, sizeof(repl_null));
7435 memset(repl_repl, false, sizeof(repl_repl));
7437 repl_repl[Anum_pg_class_relowner - 1] = true;
7438 repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
7441 * Determine the modified ACL for the new owner. This is only
7442 * necessary when the ACL is non-null.
7444 aclDatum = SysCacheGetAttr(RELOID, tuple,
7445 Anum_pg_class_relacl,
7449 newAcl = aclnewowner(DatumGetAclP(aclDatum),
7450 tuple_class->relowner, newOwnerId);
7451 repl_repl[Anum_pg_class_relacl - 1] = true;
7452 repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
7455 newtuple = heap_modify_tuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl);
7457 simple_heap_update(class_rel, &newtuple->t_self, newtuple);
7458 CatalogUpdateIndexes(class_rel, newtuple);
7460 heap_freetuple(newtuple);
7463 * Update owner dependency reference, if any. A composite type has
7464 * none, because it's tracked for the pg_type entry instead of here;
7465 * indexes and TOAST tables don't have their own entries either.
7467 if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
7468 tuple_class->relkind != RELKIND_INDEX &&
7469 tuple_class->relkind != RELKIND_TOASTVALUE)
7470 changeDependencyOnOwner(RelationRelationId, relationOid,
7474 * Also change the ownership of the table's rowtype, if it has one
7476 if (tuple_class->relkind != RELKIND_INDEX)
7477 AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId,
7478 tuple_class->relkind == RELKIND_COMPOSITE_TYPE);
7481 * If we are operating on a table, also change the ownership of any
7482 * indexes and sequences that belong to the table, as well as the
7483 * table's toast table (if it has one)
7485 if (tuple_class->relkind == RELKIND_RELATION ||
7486 tuple_class->relkind == RELKIND_TOASTVALUE)
7488 List *index_oid_list;
7491 /* Find all the indexes belonging to this relation */
7492 index_oid_list = RelationGetIndexList(target_rel);
7494 /* For each index, recursively change its ownership */
7495 foreach(i, index_oid_list)
7496 ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode);
7498 list_free(index_oid_list);
7501 if (tuple_class->relkind == RELKIND_RELATION)
7503 /* If it has a toast table, recurse to change its ownership */
7504 if (tuple_class->reltoastrelid != InvalidOid)
7505 ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId,
7508 /* If it has dependent sequences, recurse to change them too */
7509 change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode);
7513 ReleaseSysCache(tuple);
7514 heap_close(class_rel, RowExclusiveLock);
7515 relation_close(target_rel, NoLock);
7519 * change_owner_recurse_to_sequences
7521 * Helper function for ATExecChangeOwner. Examines pg_depend searching
7522 * for sequences that are dependent on serial columns, and changes their
7526 change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lockmode)
7534 * SERIAL sequences are those having an auto dependency on one of the
7535 * table's columns (we don't care *which* column, exactly).
7537 depRel = heap_open(DependRelationId, AccessShareLock);
7539 ScanKeyInit(&key[0],
7540 Anum_pg_depend_refclassid,
7541 BTEqualStrategyNumber, F_OIDEQ,
7542 ObjectIdGetDatum(RelationRelationId));
7543 ScanKeyInit(&key[1],
7544 Anum_pg_depend_refobjid,
7545 BTEqualStrategyNumber, F_OIDEQ,
7546 ObjectIdGetDatum(relationOid));
7547 /* we leave refobjsubid unspecified */
7549 scan = systable_beginscan(depRel, DependReferenceIndexId, true,
7550 SnapshotNow, 2, key);
7552 while (HeapTupleIsValid(tup = systable_getnext(scan)))
7554 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
7557 /* skip dependencies other than auto dependencies on columns */
7558 if (depForm->refobjsubid == 0 ||
7559 depForm->classid != RelationRelationId ||
7560 depForm->objsubid != 0 ||
7561 depForm->deptype != DEPENDENCY_AUTO)
7564 /* Use relation_open just in case it's an index */
7565 seqRel = relation_open(depForm->objid, lockmode);
7567 /* skip non-sequence relations */
7568 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
7570 /* No need to keep the lock */
7571 relation_close(seqRel, lockmode);
7575 /* We don't need to close the sequence while we alter it. */
7576 ATExecChangeOwner(depForm->objid, newOwnerId, true, lockmode);
7578 /* Now we can close it. Keep the lock till end of transaction. */
7579 relation_close(seqRel, NoLock);
7582 systable_endscan(scan);
7584 relation_close(depRel, AccessShareLock);
7588 * ALTER TABLE CLUSTER ON
7590 * The only thing we have to do is to change the indisclustered bits.
7593 ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode)
7597 indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
7599 if (!OidIsValid(indexOid))
7601 (errcode(ERRCODE_UNDEFINED_OBJECT),
7602 errmsg("index \"%s\" for table \"%s\" does not exist",
7603 indexName, RelationGetRelationName(rel))));
7605 /* Check index is valid to cluster on */
7606 check_index_is_clusterable(rel, indexOid, false, lockmode);
7608 /* And do the work */
7609 mark_index_clustered(rel, indexOid);
7613 * ALTER TABLE SET WITHOUT CLUSTER
7615 * We have to find any indexes on the table that have indisclustered bit
7616 * set and turn it off.
7619 ATExecDropCluster(Relation rel, LOCKMODE lockmode)
7621 mark_index_clustered(rel, InvalidOid);
7625 * ALTER TABLE SET TABLESPACE
7628 ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename, LOCKMODE lockmode)
7631 AclResult aclresult;
7633 /* Check that the tablespace exists */
7634 tablespaceId = get_tablespace_oid(tablespacename, false);
7636 /* Check its permissions */
7637 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
7638 if (aclresult != ACLCHECK_OK)
7639 aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
7641 /* Save info for Phase 3 to do the real work */
7642 if (OidIsValid(tab->newTableSpace))
7644 (errcode(ERRCODE_SYNTAX_ERROR),
7645 errmsg("cannot have multiple SET TABLESPACE subcommands")));
7646 tab->newTableSpace = tablespaceId;
7650 * ALTER TABLE/INDEX SET (...) or RESET (...)
7653 ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode)
7662 Datum repl_val[Natts_pg_class];
7663 bool repl_null[Natts_pg_class];
7664 bool repl_repl[Natts_pg_class];
7665 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
7668 return; /* nothing to do */
7670 pgclass = heap_open(RelationRelationId, RowExclusiveLock);
7672 /* Get the old reloptions */
7673 relid = RelationGetRelid(rel);
7674 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
7675 if (!HeapTupleIsValid(tuple))
7676 elog(ERROR, "cache lookup failed for relation %u", relid);
7678 datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
7680 /* Generate new proposed reloptions (text array) */
7681 newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
7682 defList, NULL, validnsps, false, isReset);
7685 switch (rel->rd_rel->relkind)
7687 case RELKIND_RELATION:
7688 case RELKIND_TOASTVALUE:
7689 (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
7692 (void) index_reloptions(rel->rd_am->amoptions, newOptions, true);
7696 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7697 errmsg("\"%s\" is not a table, index, or TOAST table",
7698 RelationGetRelationName(rel))));
7703 * All we need do here is update the pg_class row; the new options will be
7704 * propagated into relcaches during post-commit cache inval.
7706 memset(repl_val, 0, sizeof(repl_val));
7707 memset(repl_null, false, sizeof(repl_null));
7708 memset(repl_repl, false, sizeof(repl_repl));
7710 if (newOptions != (Datum) 0)
7711 repl_val[Anum_pg_class_reloptions - 1] = newOptions;
7713 repl_null[Anum_pg_class_reloptions - 1] = true;
7715 repl_repl[Anum_pg_class_reloptions - 1] = true;
7717 newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
7718 repl_val, repl_null, repl_repl);
7720 simple_heap_update(pgclass, &newtuple->t_self, newtuple);
7722 CatalogUpdateIndexes(pgclass, newtuple);
7724 heap_freetuple(newtuple);
7726 ReleaseSysCache(tuple);
7728 /* repeat the whole exercise for the toast table, if there's one */
7729 if (OidIsValid(rel->rd_rel->reltoastrelid))
7732 Oid toastid = rel->rd_rel->reltoastrelid;
7734 toastrel = heap_open(toastid, lockmode);
7736 /* Get the old reloptions */
7737 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
7738 if (!HeapTupleIsValid(tuple))
7739 elog(ERROR, "cache lookup failed for relation %u", toastid);
7741 datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
7743 newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
7744 defList, "toast", validnsps, false, isReset);
7746 (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
7748 memset(repl_val, 0, sizeof(repl_val));
7749 memset(repl_null, false, sizeof(repl_null));
7750 memset(repl_repl, false, sizeof(repl_repl));
7752 if (newOptions != (Datum) 0)
7753 repl_val[Anum_pg_class_reloptions - 1] = newOptions;
7755 repl_null[Anum_pg_class_reloptions - 1] = true;
7757 repl_repl[Anum_pg_class_reloptions - 1] = true;
7759 newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
7760 repl_val, repl_null, repl_repl);
7762 simple_heap_update(pgclass, &newtuple->t_self, newtuple);
7764 CatalogUpdateIndexes(pgclass, newtuple);
7766 heap_freetuple(newtuple);
7768 ReleaseSysCache(tuple);
7770 heap_close(toastrel, NoLock);
7773 heap_close(pgclass, RowExclusiveLock);
7777 * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
7778 * rewriting to be done, so we just want to copy the data as fast as possible.
7781 ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
7788 RelFileNode newrnode;
7789 SMgrRelation dstrel;
7792 Form_pg_class rd_rel;
7796 * Need lock here in case we are recursing to toast table or index
7798 rel = relation_open(tableOid, lockmode);
7801 * No work if no change in tablespace.
7803 oldTableSpace = rel->rd_rel->reltablespace;
7804 if (newTableSpace == oldTableSpace ||
7805 (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
7807 relation_close(rel, NoLock);
7812 * We cannot support moving mapped relations into different tablespaces.
7813 * (In particular this eliminates all shared catalogs.)
7815 if (RelationIsMapped(rel))
7817 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7818 errmsg("cannot move system relation \"%s\"",
7819 RelationGetRelationName(rel))));
7821 /* Can't move a non-shared relation into pg_global */
7822 if (newTableSpace == GLOBALTABLESPACE_OID)
7824 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
7825 errmsg("only shared relations can be placed in pg_global tablespace")));
7828 * Don't allow moving temp tables of other backends ... their local buffer
7829 * manager is not going to cope.
7831 if (RELATION_IS_OTHER_TEMP(rel))
7833 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7834 errmsg("cannot move temporary tables of other sessions")));
7836 reltoastrelid = rel->rd_rel->reltoastrelid;
7837 reltoastidxid = rel->rd_rel->reltoastidxid;
7839 /* Get a modifiable copy of the relation's pg_class row */
7840 pg_class = heap_open(RelationRelationId, RowExclusiveLock);
7842 tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(tableOid));
7843 if (!HeapTupleIsValid(tuple))
7844 elog(ERROR, "cache lookup failed for relation %u", tableOid);
7845 rd_rel = (Form_pg_class) GETSTRUCT(tuple);
7848 * Since we copy the file directly without looking at the shared buffers,
7849 * we'd better first flush out any pages of the source relation that are
7850 * in shared buffers. We assume no new changes will be made while we are
7851 * holding exclusive lock on the rel.
7853 FlushRelationBuffers(rel);
7856 * Relfilenodes are not unique across tablespaces, so we need to allocate
7857 * a new one in the new tablespace.
7859 newrelfilenode = GetNewRelFileNode(newTableSpace, NULL,
7860 rel->rd_rel->relpersistence);
7862 /* Open old and new relation */
7863 newrnode = rel->rd_node;
7864 newrnode.relNode = newrelfilenode;
7865 newrnode.spcNode = newTableSpace;
7866 dstrel = smgropen(newrnode, rel->rd_backend);
7868 RelationOpenSmgr(rel);
7871 * Create and copy all forks of the relation, and schedule unlinking of
7872 * old physical files.
7874 * NOTE: any conflict in relfilenode value will be caught in
7875 * RelationCreateStorage().
7877 RelationCreateStorage(newrnode, rel->rd_rel->relpersistence);
7879 /* copy main fork */
7880 copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM,
7881 rel->rd_rel->relpersistence);
7883 /* copy those extra forks that exist */
7884 for (forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++)
7886 if (smgrexists(rel->rd_smgr, forkNum))
7888 smgrcreate(dstrel, forkNum, false);
7889 copy_relation_data(rel->rd_smgr, dstrel, forkNum,
7890 rel->rd_rel->relpersistence);
7894 /* drop old relation, and close new one */
7895 RelationDropStorage(rel);
7898 /* update the pg_class row */
7899 rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
7900 rd_rel->relfilenode = newrelfilenode;
7901 simple_heap_update(pg_class, &tuple->t_self, tuple);
7902 CatalogUpdateIndexes(pg_class, tuple);
7904 heap_freetuple(tuple);
7906 heap_close(pg_class, RowExclusiveLock);
7908 relation_close(rel, NoLock);
7910 /* Make sure the reltablespace change is visible */
7911 CommandCounterIncrement();
7913 /* Move associated toast relation and/or index, too */
7914 if (OidIsValid(reltoastrelid))
7915 ATExecSetTableSpace(reltoastrelid, newTableSpace, lockmode);
7916 if (OidIsValid(reltoastidxid))
7917 ATExecSetTableSpace(reltoastidxid, newTableSpace, lockmode);
7921 * Copy data, block by block
7924 copy_relation_data(SMgrRelation src, SMgrRelation dst,
7925 ForkNumber forkNum, char relpersistence)
7930 BlockNumber nblocks;
7934 * palloc the buffer so that it's MAXALIGN'd. If it were just a local
7935 * char[] array, the compiler might align it on any byte boundary, which
7936 * can seriously hurt transfer speed to and from the kernel; not to
7937 * mention possibly making log_newpage's accesses to the page header fail.
7939 buf = (char *) palloc(BLCKSZ);
7943 * We need to log the copied data in WAL iff WAL archiving/streaming is
7944 * enabled AND it's a permanent relation.
7946 use_wal = XLogIsNeeded() && relpersistence == RELPERSISTENCE_PERMANENT;
7948 nblocks = smgrnblocks(src, forkNum);
7950 for (blkno = 0; blkno < nblocks; blkno++)
7952 /* If we got a cancel signal during the copy of the data, quit */
7953 CHECK_FOR_INTERRUPTS();
7955 smgrread(src, forkNum, blkno, buf);
7959 log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page);
7962 * Now write the page. We say isTemp = true even if it's not a temp
7963 * rel, because there's no need for smgr to schedule an fsync for this
7964 * write; we'll do it ourselves below.
7966 smgrextend(dst, forkNum, blkno, buf, true);
7972 * If the rel isn't temp, we must fsync it down to disk before it's safe
7973 * to commit the transaction. (For a temp rel we don't care since the rel
7974 * will be uninteresting after a crash anyway.)
7976 * It's obvious that we must do this when not WAL-logging the copy. It's
7977 * less obvious that we have to do it even if we did WAL-log the copied
7978 * pages. The reason is that since we're copying outside shared buffers, a
7979 * CHECKPOINT occurring during the copy has no way to flush the previously
7980 * written data to disk (indeed it won't know the new rel even exists). A
7981 * crash later on would replay WAL from the checkpoint, therefore it
7982 * wouldn't replay our earlier WAL entries. If we do not fsync those pages
7983 * here, they might still not be on disk when the crash occurs.
7985 if (relpersistence == RELPERSISTENCE_PERMANENT)
7986 smgrimmedsync(dst, forkNum);
7990 * ALTER TABLE ENABLE/DISABLE TRIGGER
7992 * We just pass this off to trigger.c.
7995 ATExecEnableDisableTrigger(Relation rel, char *trigname,
7996 char fires_when, bool skip_system, LOCKMODE lockmode)
7998 EnableDisableTrigger(rel, trigname, fires_when, skip_system);
8002 * ALTER TABLE ENABLE/DISABLE RULE
8004 * We just pass this off to rewriteDefine.c.
8007 ATExecEnableDisableRule(Relation rel, char *trigname,
8008 char fires_when, LOCKMODE lockmode)
8010 EnableDisableRule(rel, trigname, fires_when);
8014 * ALTER TABLE INHERIT
8016 * Add a parent to the child's parents. This verifies that all the columns and
8017 * check constraints of the parent appear in the child and that they have the
8018 * same data types and expressions.
8021 ATPrepAddInherit(Relation child_rel)
8023 if (child_rel->rd_rel->reloftype)
8025 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8026 errmsg("cannot change inheritance of typed table")));
8030 ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
8032 Relation parent_rel,
8036 HeapTuple inheritsTuple;
8041 * A self-exclusive lock is needed here. See the similar case in
8042 * MergeAttributes() for a full explanation.
8044 parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock);
8047 * Must be owner of both parent and child -- child was checked by
8048 * ATSimplePermissions call in ATPrepCmd
8050 ATSimplePermissions(parent_rel, ATT_TABLE);
8052 /* Permanent rels cannot inherit from temporary ones */
8053 if (RelationUsesTempNamespace(parent_rel)
8054 && !RelationUsesTempNamespace(child_rel))
8056 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8057 errmsg("cannot inherit from temporary relation \"%s\"",
8058 RelationGetRelationName(parent_rel))));
8061 * Check for duplicates in the list of parents, and determine the highest
8062 * inhseqno already present; we'll use the next one for the new parent.
8063 * (Note: get RowExclusiveLock because we will write pg_inherits below.)
8065 * Note: we do not reject the case where the child already inherits from
8066 * the parent indirectly; CREATE TABLE doesn't reject comparable cases.
8068 catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
8070 Anum_pg_inherits_inhrelid,
8071 BTEqualStrategyNumber, F_OIDEQ,
8072 ObjectIdGetDatum(RelationGetRelid(child_rel)));
8073 scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
8074 true, SnapshotNow, 1, &key);
8076 /* inhseqno sequences start at 1 */
8078 while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
8080 Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inheritsTuple);
8082 if (inh->inhparent == RelationGetRelid(parent_rel))
8084 (errcode(ERRCODE_DUPLICATE_TABLE),
8085 errmsg("relation \"%s\" would be inherited from more than once",
8086 RelationGetRelationName(parent_rel))));
8087 if (inh->inhseqno > inhseqno)
8088 inhseqno = inh->inhseqno;
8090 systable_endscan(scan);
8093 * Prevent circularity by seeing if proposed parent inherits from child.
8094 * (In particular, this disallows making a rel inherit from itself.)
8096 * This is not completely bulletproof because of race conditions: in
8097 * multi-level inheritance trees, someone else could concurrently be
8098 * making another inheritance link that closes the loop but does not join
8099 * either of the rels we have locked. Preventing that seems to require
8100 * exclusive locks on the entire inheritance tree, which is a cure worse
8101 * than the disease. find_all_inheritors() will cope with circularity
8102 * anyway, so don't sweat it too much.
8104 * We use weakest lock we can on child's children, namely AccessShareLock.
8106 children = find_all_inheritors(RelationGetRelid(child_rel),
8107 AccessShareLock, NULL);
8109 if (list_member_oid(children, RelationGetRelid(parent_rel)))
8111 (errcode(ERRCODE_DUPLICATE_TABLE),
8112 errmsg("circular inheritance not allowed"),
8113 errdetail("\"%s\" is already a child of \"%s\".",
8115 RelationGetRelationName(child_rel))));
8117 /* If parent has OIDs then child must have OIDs */
8118 if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
8120 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8121 errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
8122 RelationGetRelationName(child_rel),
8123 RelationGetRelationName(parent_rel))));
8125 /* Match up the columns and bump attinhcount as needed */
8126 MergeAttributesIntoExisting(child_rel, parent_rel);
8128 /* Match up the constraints and bump coninhcount as needed */
8129 MergeConstraintsIntoExisting(child_rel, parent_rel);
8132 * OK, it looks valid. Make the catalog entries that show inheritance.
8134 StoreCatalogInheritance1(RelationGetRelid(child_rel),
8135 RelationGetRelid(parent_rel),
8139 /* Now we're done with pg_inherits */
8140 heap_close(catalogRelation, RowExclusiveLock);
8142 /* keep our lock on the parent relation until commit */
8143 heap_close(parent_rel, NoLock);
8147 * Obtain the source-text form of the constraint expression for a check
8148 * constraint, given its pg_constraint tuple
8151 decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
8153 Form_pg_constraint con;
8158 con = (Form_pg_constraint) GETSTRUCT(contup);
8159 attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
8161 elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));
8163 expr = DirectFunctionCall2(pg_get_expr, attr,
8164 ObjectIdGetDatum(con->conrelid));
8165 return TextDatumGetCString(expr);
8169 * Determine whether two check constraints are functionally equivalent
8171 * The test we apply is to see whether they reverse-compile to the same
8172 * source string. This insulates us from issues like whether attributes
8173 * have the same physical column numbers in parent and child relations.
8176 constraints_equivalent(HeapTuple a, HeapTuple b, TupleDesc tupleDesc)
8178 Form_pg_constraint acon = (Form_pg_constraint) GETSTRUCT(a);
8179 Form_pg_constraint bcon = (Form_pg_constraint) GETSTRUCT(b);
8181 if (acon->condeferrable != bcon->condeferrable ||
8182 acon->condeferred != bcon->condeferred ||
8183 strcmp(decompile_conbin(a, tupleDesc),
8184 decompile_conbin(b, tupleDesc)) != 0)
8191 * Check columns in child table match up with columns in parent, and increment
8192 * their attinhcount.
8194 * Called by ATExecAddInherit
8196 * Currently all parent columns must be found in child. Missing columns are an
8197 * error. One day we might consider creating new columns like CREATE TABLE
8198 * does. However, that is widely unpopular --- in the common use case of
8199 * partitioned tables it's a foot-gun.
8201 * The data type must match exactly. If the parent column is NOT NULL then
8202 * the child must be as well. Defaults are not compared, however.
8205 MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
8208 AttrNumber parent_attno;
8210 TupleDesc tupleDesc;
8213 attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
8215 tupleDesc = RelationGetDescr(parent_rel);
8216 parent_natts = tupleDesc->natts;
8218 for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
8220 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
8221 char *attributeName = NameStr(attribute->attname);
8223 /* Ignore dropped columns in the parent. */
8224 if (attribute->attisdropped)
8227 /* Find same column in child (matching on column name). */
8228 tuple = SearchSysCacheCopyAttName(RelationGetRelid(child_rel),
8230 if (HeapTupleIsValid(tuple))
8232 /* Check they are same type, typmod, and collation */
8233 Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
8235 if (attribute->atttypid != childatt->atttypid ||
8236 attribute->atttypmod != childatt->atttypmod)
8238 (errcode(ERRCODE_DATATYPE_MISMATCH),
8239 errmsg("child table \"%s\" has different type for column \"%s\"",
8240 RelationGetRelationName(child_rel),
8243 if (attribute->attcollation != childatt->attcollation)
8245 (errcode(ERRCODE_COLLATION_MISMATCH),
8246 errmsg("child table \"%s\" has different collation for column \"%s\"",
8247 RelationGetRelationName(child_rel),
8251 * Check child doesn't discard NOT NULL property. (Other
8252 * constraints are checked elsewhere.)
8254 if (attribute->attnotnull && !childatt->attnotnull)
8256 (errcode(ERRCODE_DATATYPE_MISMATCH),
8257 errmsg("column \"%s\" in child table must be marked NOT NULL",
8261 * OK, bump the child column's inheritance count. (If we fail
8262 * later on, this change will just roll back.)
8264 childatt->attinhcount++;
8265 simple_heap_update(attrrel, &tuple->t_self, tuple);
8266 CatalogUpdateIndexes(attrrel, tuple);
8267 heap_freetuple(tuple);
8272 (errcode(ERRCODE_DATATYPE_MISMATCH),
8273 errmsg("child table is missing column \"%s\"",
8278 heap_close(attrrel, RowExclusiveLock);
8282 * Check constraints in child table match up with constraints in parent,
8283 * and increment their coninhcount.
8285 * Called by ATExecAddInherit
8287 * Currently all constraints in parent must be present in the child. One day we
8288 * may consider adding new constraints like CREATE TABLE does. We may also want
8289 * to allow an optional flag on parent table constraints indicating they are
8290 * intended to ONLY apply to the master table, not to the children. That would
8291 * make it possible to ensure no records are mistakenly inserted into the
8292 * master in partitioned tables rather than the appropriate child.
8294 * XXX This is O(N^2) which may be an issue with tables with hundreds of
8295 * constraints. As long as tables have more like 10 constraints it shouldn't be
8296 * a problem though. Even 100 constraints ought not be the end of the world.
8299 MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
8301 Relation catalog_relation;
8302 TupleDesc tuple_desc;
8303 SysScanDesc parent_scan;
8304 ScanKeyData parent_key;
8305 HeapTuple parent_tuple;
8307 catalog_relation = heap_open(ConstraintRelationId, RowExclusiveLock);
8308 tuple_desc = RelationGetDescr(catalog_relation);
8310 /* Outer loop scans through the parent's constraint definitions */
8311 ScanKeyInit(&parent_key,
8312 Anum_pg_constraint_conrelid,
8313 BTEqualStrategyNumber, F_OIDEQ,
8314 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
8315 parent_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
8316 true, SnapshotNow, 1, &parent_key);
8318 while (HeapTupleIsValid(parent_tuple = systable_getnext(parent_scan)))
8320 Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(parent_tuple);
8321 SysScanDesc child_scan;
8322 ScanKeyData child_key;
8323 HeapTuple child_tuple;
8326 if (parent_con->contype != CONSTRAINT_CHECK)
8329 /* Search for a child constraint matching this one */
8330 ScanKeyInit(&child_key,
8331 Anum_pg_constraint_conrelid,
8332 BTEqualStrategyNumber, F_OIDEQ,
8333 ObjectIdGetDatum(RelationGetRelid(child_rel)));
8334 child_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
8335 true, SnapshotNow, 1, &child_key);
8337 while (HeapTupleIsValid(child_tuple = systable_getnext(child_scan)))
8339 Form_pg_constraint child_con = (Form_pg_constraint) GETSTRUCT(child_tuple);
8340 HeapTuple child_copy;
8342 if (child_con->contype != CONSTRAINT_CHECK)
8345 if (strcmp(NameStr(parent_con->conname),
8346 NameStr(child_con->conname)) != 0)
8349 if (!constraints_equivalent(parent_tuple, child_tuple, tuple_desc))
8351 (errcode(ERRCODE_DATATYPE_MISMATCH),
8352 errmsg("child table \"%s\" has different definition for check constraint \"%s\"",
8353 RelationGetRelationName(child_rel),
8354 NameStr(parent_con->conname))));
8357 * OK, bump the child constraint's inheritance count. (If we fail
8358 * later on, this change will just roll back.)
8360 child_copy = heap_copytuple(child_tuple);
8361 child_con = (Form_pg_constraint) GETSTRUCT(child_copy);
8362 child_con->coninhcount++;
8363 simple_heap_update(catalog_relation, &child_copy->t_self, child_copy);
8364 CatalogUpdateIndexes(catalog_relation, child_copy);
8365 heap_freetuple(child_copy);
8371 systable_endscan(child_scan);
8375 (errcode(ERRCODE_DATATYPE_MISMATCH),
8376 errmsg("child table is missing constraint \"%s\"",
8377 NameStr(parent_con->conname))));
8380 systable_endscan(parent_scan);
8381 heap_close(catalog_relation, RowExclusiveLock);
8385 * ALTER TABLE NO INHERIT
8387 * Drop a parent from the child's parents. This just adjusts the attinhcount
8388 * and attislocal of the columns and removes the pg_inherit and pg_depend
8391 * If attinhcount goes to 0 then attislocal gets set to true. If it goes back
8392 * up attislocal stays true, which means if a child is ever removed from a
8393 * parent then its columns will never be automatically dropped which may
8394 * surprise. But at least we'll never surprise by dropping columns someone
8395 * isn't expecting to be dropped which would actually mean data loss.
8397 * coninhcount and conislocal for inherited constraints are adjusted in
8398 * exactly the same way.
8401 ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode)
8403 Relation parent_rel;
8404 Relation catalogRelation;
8407 HeapTuple inheritsTuple,
8414 * AccessShareLock on the parent is probably enough, seeing that DROP
8415 * TABLE doesn't lock parent tables at all. We need some lock since we'll
8416 * be inspecting the parent's schema.
8418 parent_rel = heap_openrv(parent, AccessShareLock);
8421 * We don't bother to check ownership of the parent table --- ownership of
8422 * the child is presumed enough rights.
8426 * Find and destroy the pg_inherits entry linking the two, or error out if
8429 catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
8430 ScanKeyInit(&key[0],
8431 Anum_pg_inherits_inhrelid,
8432 BTEqualStrategyNumber, F_OIDEQ,
8433 ObjectIdGetDatum(RelationGetRelid(rel)));
8434 scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
8435 true, SnapshotNow, 1, key);
8437 while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
8441 inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
8442 if (inhparent == RelationGetRelid(parent_rel))
8444 simple_heap_delete(catalogRelation, &inheritsTuple->t_self);
8450 systable_endscan(scan);
8451 heap_close(catalogRelation, RowExclusiveLock);
8455 (errcode(ERRCODE_UNDEFINED_TABLE),
8456 errmsg("relation \"%s\" is not a parent of relation \"%s\"",
8457 RelationGetRelationName(parent_rel),
8458 RelationGetRelationName(rel))));
8461 * Search through child columns looking for ones matching parent rel
8463 catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock);
8464 ScanKeyInit(&key[0],
8465 Anum_pg_attribute_attrelid,
8466 BTEqualStrategyNumber, F_OIDEQ,
8467 ObjectIdGetDatum(RelationGetRelid(rel)));
8468 scan = systable_beginscan(catalogRelation, AttributeRelidNumIndexId,
8469 true, SnapshotNow, 1, key);
8470 while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
8472 Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
8474 /* Ignore if dropped or not inherited */
8475 if (att->attisdropped)
8477 if (att->attinhcount <= 0)
8480 if (SearchSysCacheExistsAttName(RelationGetRelid(parent_rel),
8481 NameStr(att->attname)))
8483 /* Decrement inhcount and possibly set islocal to true */
8484 HeapTuple copyTuple = heap_copytuple(attributeTuple);
8485 Form_pg_attribute copy_att = (Form_pg_attribute) GETSTRUCT(copyTuple);
8487 copy_att->attinhcount--;
8488 if (copy_att->attinhcount == 0)
8489 copy_att->attislocal = true;
8491 simple_heap_update(catalogRelation, ©Tuple->t_self, copyTuple);
8492 CatalogUpdateIndexes(catalogRelation, copyTuple);
8493 heap_freetuple(copyTuple);
8496 systable_endscan(scan);
8497 heap_close(catalogRelation, RowExclusiveLock);
8500 * Likewise, find inherited check constraints and disinherit them. To do
8501 * this, we first need a list of the names of the parent's check
8502 * constraints. (We cheat a bit by only checking for name matches,
8503 * assuming that the expressions will match.)
8505 catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock);
8506 ScanKeyInit(&key[0],
8507 Anum_pg_constraint_conrelid,
8508 BTEqualStrategyNumber, F_OIDEQ,
8509 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
8510 scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
8511 true, SnapshotNow, 1, key);
8515 while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
8517 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
8519 if (con->contype == CONSTRAINT_CHECK)
8520 connames = lappend(connames, pstrdup(NameStr(con->conname)));
8523 systable_endscan(scan);
8525 /* Now scan the child's constraints */
8526 ScanKeyInit(&key[0],
8527 Anum_pg_constraint_conrelid,
8528 BTEqualStrategyNumber, F_OIDEQ,
8529 ObjectIdGetDatum(RelationGetRelid(rel)));
8530 scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
8531 true, SnapshotNow, 1, key);
8533 while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
8535 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
8539 if (con->contype != CONSTRAINT_CHECK)
8543 foreach(lc, connames)
8545 if (strcmp(NameStr(con->conname), (char *) lfirst(lc)) == 0)
8554 /* Decrement inhcount and possibly set islocal to true */
8555 HeapTuple copyTuple = heap_copytuple(constraintTuple);
8556 Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
8558 if (copy_con->coninhcount <= 0) /* shouldn't happen */
8559 elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
8560 RelationGetRelid(rel), NameStr(copy_con->conname));
8562 copy_con->coninhcount--;
8563 if (copy_con->coninhcount == 0)
8564 copy_con->conislocal = true;
8566 simple_heap_update(catalogRelation, ©Tuple->t_self, copyTuple);
8567 CatalogUpdateIndexes(catalogRelation, copyTuple);
8568 heap_freetuple(copyTuple);
8572 systable_endscan(scan);
8573 heap_close(catalogRelation, RowExclusiveLock);
8575 drop_parent_dependency(RelationGetRelid(rel),
8577 RelationGetRelid(parent_rel));
8579 /* keep our lock on the parent relation until commit */
8580 heap_close(parent_rel, NoLock);
8584 * Drop the dependency created by StoreCatalogInheritance1 (CREATE TABLE
8585 * INHERITS/ALTER TABLE INHERIT -- refclassid will be RelationRelationId) or
8586 * heap_create_with_catalog (CREATE TABLE OF/ALTER TABLE OF -- refclassid will
8587 * be TypeRelationId). There's no convenient way to do this, so go trawling
8588 * through pg_depend.
8591 drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
8593 Relation catalogRelation;
8598 catalogRelation = heap_open(DependRelationId, RowExclusiveLock);
8600 ScanKeyInit(&key[0],
8601 Anum_pg_depend_classid,
8602 BTEqualStrategyNumber, F_OIDEQ,
8603 ObjectIdGetDatum(RelationRelationId));
8604 ScanKeyInit(&key[1],
8605 Anum_pg_depend_objid,
8606 BTEqualStrategyNumber, F_OIDEQ,
8607 ObjectIdGetDatum(relid));
8608 ScanKeyInit(&key[2],
8609 Anum_pg_depend_objsubid,
8610 BTEqualStrategyNumber, F_INT4EQ,
8613 scan = systable_beginscan(catalogRelation, DependDependerIndexId, true,
8614 SnapshotNow, 3, key);
8616 while (HeapTupleIsValid(depTuple = systable_getnext(scan)))
8618 Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(depTuple);
8620 if (dep->refclassid == refclassid &&
8621 dep->refobjid == refobjid &&
8622 dep->refobjsubid == 0 &&
8623 dep->deptype == DEPENDENCY_NORMAL)
8624 simple_heap_delete(catalogRelation, &depTuple->t_self);
8627 systable_endscan(scan);
8628 heap_close(catalogRelation, RowExclusiveLock);
8634 * Attach a table to a composite type, as though it had been created with CREATE
8635 * TABLE OF. All attname, atttypid, atttypmod and attcollation must match. The
8636 * subject table must not have inheritance parents. These restrictions ensure
8637 * that you cannot create a configuration impossible with CREATE TABLE OF alone.
8640 ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
8642 Oid relid = RelationGetRelid(rel);
8646 Relation inheritsRelation,
8650 AttrNumber table_attno,
8652 TupleDesc typeTupleDesc,
8654 ObjectAddress tableobj,
8656 HeapTuple classtuple;
8658 /* Validate the type. */
8659 typetuple = typenameType(NULL, ofTypename, NULL);
8660 check_of_type(typetuple);
8661 typ = (Form_pg_type) GETSTRUCT(typetuple);
8662 typeid = HeapTupleGetOid(typetuple);
8664 /* Fail if the table has any inheritance parents. */
8665 inheritsRelation = heap_open(InheritsRelationId, AccessShareLock);
8667 Anum_pg_inherits_inhrelid,
8668 BTEqualStrategyNumber, F_OIDEQ,
8669 ObjectIdGetDatum(relid));
8670 scan = systable_beginscan(inheritsRelation, InheritsRelidSeqnoIndexId,
8671 true, SnapshotNow, 1, &key);
8672 if (HeapTupleIsValid(systable_getnext(scan)))
8674 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8675 errmsg("typed tables cannot inherit")));
8676 systable_endscan(scan);
8677 heap_close(inheritsRelation, AccessShareLock);
8680 * Check the tuple descriptors for compatibility. Unlike inheritance, we
8681 * require that the order also match. However, attnotnull need not match.
8682 * Also unlike inheritance, we do not require matching relhasoids.
8684 typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1);
8685 tableTupleDesc = RelationGetDescr(rel);
8687 for (type_attno = 1; type_attno <= typeTupleDesc->natts; type_attno++)
8689 Form_pg_attribute type_attr,
8691 const char *type_attname,
8694 /* Get the next non-dropped type attribute. */
8695 type_attr = typeTupleDesc->attrs[type_attno - 1];
8696 if (type_attr->attisdropped)
8698 type_attname = NameStr(type_attr->attname);
8700 /* Get the next non-dropped table attribute. */
8703 if (table_attno > tableTupleDesc->natts)
8705 (errcode(ERRCODE_DATATYPE_MISMATCH),
8706 errmsg("table is missing column \"%s\"",
8708 table_attr = tableTupleDesc->attrs[table_attno++ - 1];
8709 } while (table_attr->attisdropped);
8710 table_attname = NameStr(table_attr->attname);
8713 if (strncmp(table_attname, type_attname, NAMEDATALEN) != 0)
8715 (errcode(ERRCODE_DATATYPE_MISMATCH),
8716 errmsg("table has column \"%s\" where type requires \"%s\"",
8717 table_attname, type_attname)));
8720 if (table_attr->atttypid != type_attr->atttypid ||
8721 table_attr->atttypmod != type_attr->atttypmod ||
8722 table_attr->attcollation != type_attr->attcollation)
8724 (errcode(ERRCODE_DATATYPE_MISMATCH),
8725 errmsg("table \"%s\" has different type for column \"%s\"",
8726 RelationGetRelationName(rel), type_attname)));
8728 DecrTupleDescRefCount(typeTupleDesc);
8730 /* Any remaining columns at the end of the table had better be dropped. */
8731 for (; table_attno <= tableTupleDesc->natts; table_attno++)
8733 Form_pg_attribute table_attr = tableTupleDesc->attrs[table_attno - 1];
8734 if (!table_attr->attisdropped)
8736 (errcode(ERRCODE_DATATYPE_MISMATCH),
8737 errmsg("table has extra column \"%s\"",
8738 NameStr(table_attr->attname))));
8741 /* If the table was already typed, drop the existing dependency. */
8742 if (rel->rd_rel->reloftype)
8743 drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
8745 /* Record a dependency on the new type. */
8746 tableobj.classId = RelationRelationId;
8747 tableobj.objectId = relid;
8748 tableobj.objectSubId = 0;
8749 typeobj.classId = TypeRelationId;
8750 typeobj.objectId = typeid;
8751 typeobj.objectSubId = 0;
8752 recordDependencyOn(&tableobj, &typeobj, DEPENDENCY_NORMAL);
8754 /* Update pg_class.reloftype */
8755 relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
8756 classtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
8757 if (!HeapTupleIsValid(classtuple))
8758 elog(ERROR, "cache lookup failed for relation %u", relid);
8759 ((Form_pg_class) GETSTRUCT(classtuple))->reloftype = typeid;
8760 simple_heap_update(relationRelation, &classtuple->t_self, classtuple);
8761 CatalogUpdateIndexes(relationRelation, classtuple);
8762 heap_freetuple(classtuple);
8763 heap_close(relationRelation, RowExclusiveLock);
8765 ReleaseSysCache(typetuple);
8769 * ALTER TABLE NOT OF
8771 * Detach a typed table from its originating type. Just clear reloftype and
8772 * remove the dependency.
8775 ATExecDropOf(Relation rel, LOCKMODE lockmode)
8777 Oid relid = RelationGetRelid(rel);
8778 Relation relationRelation;
8781 if (!OidIsValid(rel->rd_rel->reloftype))
8783 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8784 errmsg("\"%s\" is not a typed table",
8785 RelationGetRelationName(rel))));
8788 * We don't bother to check ownership of the type --- ownership of the table
8789 * is presumed enough rights. No lock required on the type, either.
8792 drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
8794 /* Clear pg_class.reloftype */
8795 relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
8796 tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
8797 if (!HeapTupleIsValid(tuple))
8798 elog(ERROR, "cache lookup failed for relation %u", relid);
8799 ((Form_pg_class) GETSTRUCT(tuple))->reloftype = InvalidOid;
8800 simple_heap_update(relationRelation, &tuple->t_self, tuple);
8801 CatalogUpdateIndexes(relationRelation, tuple);
8802 heap_freetuple(tuple);
8803 heap_close(relationRelation, RowExclusiveLock);
8807 * ALTER FOREIGN TABLE <name> OPTIONS (...)
8810 ATExecGenericOptions(Relation rel, List *options)
8813 ForeignServer *server;
8814 ForeignDataWrapper *fdw;
8817 Datum repl_val[Natts_pg_foreign_table];
8818 bool repl_null[Natts_pg_foreign_table];
8819 bool repl_repl[Natts_pg_foreign_table];
8821 Form_pg_foreign_table tableform;
8826 ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock);
8828 tuple = SearchSysCacheCopy1(FOREIGNTABLEREL, rel->rd_id);
8829 if (!HeapTupleIsValid(tuple))
8831 (errcode(ERRCODE_UNDEFINED_OBJECT),
8832 errmsg("foreign table \"%s\" does not exist",
8833 RelationGetRelationName(rel))));
8834 tableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
8835 server = GetForeignServer(tableform->ftserver);
8836 fdw = GetForeignDataWrapper(server->fdwid);
8838 memset(repl_val, 0, sizeof(repl_val));
8839 memset(repl_null, false, sizeof(repl_null));
8840 memset(repl_repl, false, sizeof(repl_repl));
8842 /* Extract the current options */
8843 datum = SysCacheGetAttr(FOREIGNTABLEREL,
8845 Anum_pg_foreign_table_ftoptions,
8848 datum = PointerGetDatum(NULL);
8850 /* Transform the options */
8851 datum = transformGenericOptions(ForeignTableRelationId,
8856 if (PointerIsValid(DatumGetPointer(datum)))
8857 repl_val[Anum_pg_foreign_table_ftoptions - 1] = datum;
8859 repl_null[Anum_pg_foreign_table_ftoptions - 1] = true;
8861 repl_repl[Anum_pg_foreign_table_ftoptions - 1] = true;
8863 /* Everything looks good - update the tuple */
8865 tuple = heap_modify_tuple(tuple, RelationGetDescr(ftrel),
8866 repl_val, repl_null, repl_repl);
8868 simple_heap_update(ftrel, &tuple->t_self, tuple);
8869 CatalogUpdateIndexes(ftrel, tuple);
8871 heap_close(ftrel, RowExclusiveLock);
8873 heap_freetuple(tuple);
8878 * Execute ALTER TABLE SET SCHEMA
8880 * Note: caller must have checked ownership of the relation already
8883 AlterTableNamespace(RangeVar *relation, const char *newschema,
8884 ObjectType stmttype, LOCKMODE lockmode)
8892 rel = relation_openrv(relation, lockmode);
8894 relid = RelationGetRelid(rel);
8895 oldNspOid = RelationGetNamespace(rel);
8897 /* Check relation type against type specified in the ALTER command */
8903 * For mostly-historical reasons, we allow ALTER TABLE to apply to
8904 * all relation types.
8908 case OBJECT_SEQUENCE:
8909 if (rel->rd_rel->relkind != RELKIND_SEQUENCE)
8911 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8912 errmsg("\"%s\" is not a sequence",
8913 RelationGetRelationName(rel))));
8917 if (rel->rd_rel->relkind != RELKIND_VIEW)
8919 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8920 errmsg("\"%s\" is not a view",
8921 RelationGetRelationName(rel))));
8924 case OBJECT_FOREIGN_TABLE:
8925 if (rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
8927 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8928 errmsg("\"%s\" is not a foreign table",
8929 RelationGetRelationName(rel))));
8933 elog(ERROR, "unrecognized object type: %d", (int) stmttype);
8936 /* Can we change the schema of this tuple? */
8937 switch (rel->rd_rel->relkind)
8939 case RELKIND_RELATION:
8941 case RELKIND_FOREIGN_TABLE:
8942 /* ok to change schema */
8944 case RELKIND_SEQUENCE:
8946 /* if it's an owned sequence, disallow moving it by itself */
8950 if (sequenceIsOwned(relid, &tableId, &colId))
8952 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8953 errmsg("cannot move an owned sequence into another schema"),
8954 errdetail("Sequence \"%s\" is linked to table \"%s\".",
8955 RelationGetRelationName(rel),
8956 get_rel_name(tableId))));
8959 case RELKIND_COMPOSITE_TYPE:
8961 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8962 errmsg("\"%s\" is a composite type",
8963 RelationGetRelationName(rel)),
8964 errhint("Use ALTER TYPE instead.")));
8967 case RELKIND_TOASTVALUE:
8971 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8972 errmsg("\"%s\" is not a table, view, sequence, or foreign table",
8973 RelationGetRelationName(rel))));
8976 /* get schema OID and check its permissions */
8977 nspOid = LookupCreationNamespace(newschema);
8979 /* common checks on switching namespaces */
8980 CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
8982 /* OK, modify the pg_class row and pg_depend entry */
8983 classRel = heap_open(RelationRelationId, RowExclusiveLock);
8985 AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true);
8987 /* Fix the table's rowtype too */
8988 AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false);
8990 /* Fix other dependent stuff */
8991 if (rel->rd_rel->relkind == RELKIND_RELATION)
8993 AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid);
8994 AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid, newschema, lockmode);
8995 AlterConstraintNamespaces(relid, oldNspOid, nspOid, false);
8998 heap_close(classRel, RowExclusiveLock);
9000 /* close rel, but keep lock until commit */
9001 relation_close(rel, NoLock);
9005 * The guts of relocating a relation to another namespace: fix the pg_class
9006 * entry, and the pg_depend entry if any. Caller must already have
9007 * opened and write-locked pg_class.
9010 AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
9011 Oid oldNspOid, Oid newNspOid,
9012 bool hasDependEntry)
9015 Form_pg_class classForm;
9017 classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
9018 if (!HeapTupleIsValid(classTup))
9019 elog(ERROR, "cache lookup failed for relation %u", relOid);
9020 classForm = (Form_pg_class) GETSTRUCT(classTup);
9022 Assert(classForm->relnamespace == oldNspOid);
9024 /* check for duplicate name (more friendly than unique-index failure) */
9025 if (get_relname_relid(NameStr(classForm->relname),
9026 newNspOid) != InvalidOid)
9028 (errcode(ERRCODE_DUPLICATE_TABLE),
9029 errmsg("relation \"%s\" already exists in schema \"%s\"",
9030 NameStr(classForm->relname),
9031 get_namespace_name(newNspOid))));
9033 /* classTup is a copy, so OK to scribble on */
9034 classForm->relnamespace = newNspOid;
9036 simple_heap_update(classRel, &classTup->t_self, classTup);
9037 CatalogUpdateIndexes(classRel, classTup);
9039 /* Update dependency on schema if caller said so */
9040 if (hasDependEntry &&
9041 changeDependencyFor(RelationRelationId, relOid,
9042 NamespaceRelationId, oldNspOid, newNspOid) != 1)
9043 elog(ERROR, "failed to change schema dependency for relation \"%s\"",
9044 NameStr(classForm->relname));
9046 heap_freetuple(classTup);
9050 * Move all indexes for the specified relation to another namespace.
9052 * Note: we assume adequate permission checking was done by the caller,
9053 * and that the caller has a suitable lock on the owning relation.
9056 AlterIndexNamespaces(Relation classRel, Relation rel,
9057 Oid oldNspOid, Oid newNspOid)
9062 indexList = RelationGetIndexList(rel);
9064 foreach(l, indexList)
9066 Oid indexOid = lfirst_oid(l);
9069 * Note: currently, the index will not have its own dependency on the
9070 * namespace, so we don't need to do changeDependencyFor(). There's no
9071 * rowtype in pg_type, either.
9073 AlterRelationNamespaceInternal(classRel, indexOid,
9074 oldNspOid, newNspOid,
9078 list_free(indexList);
9082 * Move all SERIAL-column sequences of the specified relation to another
9085 * Note: we assume adequate permission checking was done by the caller,
9086 * and that the caller has a suitable lock on the owning relation.
9089 AlterSeqNamespaces(Relation classRel, Relation rel,
9090 Oid oldNspOid, Oid newNspOid, const char *newNspName, LOCKMODE lockmode)
9098 * SERIAL sequences are those having an auto dependency on one of the
9099 * table's columns (we don't care *which* column, exactly).
9101 depRel = heap_open(DependRelationId, AccessShareLock);
9103 ScanKeyInit(&key[0],
9104 Anum_pg_depend_refclassid,
9105 BTEqualStrategyNumber, F_OIDEQ,
9106 ObjectIdGetDatum(RelationRelationId));
9107 ScanKeyInit(&key[1],
9108 Anum_pg_depend_refobjid,
9109 BTEqualStrategyNumber, F_OIDEQ,
9110 ObjectIdGetDatum(RelationGetRelid(rel)));
9111 /* we leave refobjsubid unspecified */
9113 scan = systable_beginscan(depRel, DependReferenceIndexId, true,
9114 SnapshotNow, 2, key);
9116 while (HeapTupleIsValid(tup = systable_getnext(scan)))
9118 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
9121 /* skip dependencies other than auto dependencies on columns */
9122 if (depForm->refobjsubid == 0 ||
9123 depForm->classid != RelationRelationId ||
9124 depForm->objsubid != 0 ||
9125 depForm->deptype != DEPENDENCY_AUTO)
9128 /* Use relation_open just in case it's an index */
9129 seqRel = relation_open(depForm->objid, lockmode);
9131 /* skip non-sequence relations */
9132 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
9134 /* No need to keep the lock */
9135 relation_close(seqRel, lockmode);
9139 /* Fix the pg_class and pg_depend entries */
9140 AlterRelationNamespaceInternal(classRel, depForm->objid,
9141 oldNspOid, newNspOid,
9145 * Sequences have entries in pg_type. We need to be careful to move
9146 * them to the new namespace, too.
9148 AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
9149 newNspOid, false, false);
9151 /* Now we can close it. Keep the lock till end of transaction. */
9152 relation_close(seqRel, NoLock);
9155 systable_endscan(scan);
9157 relation_close(depRel, AccessShareLock);
9162 * This code supports
9163 * CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
9165 * Because we only support this for TEMP tables, it's sufficient to remember
9166 * the state in a backend-local data structure.
9170 * Register a newly-created relation's ON COMMIT action.
9173 register_on_commit_action(Oid relid, OnCommitAction action)
9176 MemoryContext oldcxt;
9179 * We needn't bother registering the relation unless there is an ON COMMIT
9180 * action we need to take.
9182 if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
9185 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
9187 oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
9189 oc->oncommit = action;
9190 oc->creating_subid = GetCurrentSubTransactionId();
9191 oc->deleting_subid = InvalidSubTransactionId;
9193 on_commits = lcons(oc, on_commits);
9195 MemoryContextSwitchTo(oldcxt);
9199 * Unregister any ON COMMIT action when a relation is deleted.
9201 * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
9204 remove_on_commit_action(Oid relid)
9208 foreach(l, on_commits)
9210 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
9212 if (oc->relid == relid)
9214 oc->deleting_subid = GetCurrentSubTransactionId();
9221 * Perform ON COMMIT actions.
9223 * This is invoked just before actually committing, since it's possible
9224 * to encounter errors.
9227 PreCommit_on_commit_actions(void)
9230 List *oids_to_truncate = NIL;
9232 foreach(l, on_commits)
9234 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
9236 /* Ignore entry if already dropped in this xact */
9237 if (oc->deleting_subid != InvalidSubTransactionId)
9240 switch (oc->oncommit)
9243 case ONCOMMIT_PRESERVE_ROWS:
9244 /* Do nothing (there shouldn't be such entries, actually) */
9246 case ONCOMMIT_DELETE_ROWS:
9247 oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
9251 ObjectAddress object;
9253 object.classId = RelationRelationId;
9254 object.objectId = oc->relid;
9255 object.objectSubId = 0;
9256 performDeletion(&object, DROP_CASCADE);
9259 * Note that table deletion will call
9260 * remove_on_commit_action, so the entry should get marked
9263 Assert(oc->deleting_subid != InvalidSubTransactionId);
9268 if (oids_to_truncate != NIL)
9270 heap_truncate(oids_to_truncate);
9271 CommandCounterIncrement(); /* XXX needed? */
9276 * Post-commit or post-abort cleanup for ON COMMIT management.
9278 * All we do here is remove no-longer-needed OnCommitItem entries.
9280 * During commit, remove entries that were deleted during this transaction;
9281 * during abort, remove those created during this transaction.
9284 AtEOXact_on_commit_actions(bool isCommit)
9287 ListCell *prev_item;
9290 cur_item = list_head(on_commits);
9292 while (cur_item != NULL)
9294 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
9296 if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
9297 oc->creating_subid != InvalidSubTransactionId)
9299 /* cur_item must be removed */
9300 on_commits = list_delete_cell(on_commits, cur_item, prev_item);
9303 cur_item = lnext(prev_item);
9305 cur_item = list_head(on_commits);
9309 /* cur_item must be preserved */
9310 oc->creating_subid = InvalidSubTransactionId;
9311 oc->deleting_subid = InvalidSubTransactionId;
9312 prev_item = cur_item;
9313 cur_item = lnext(prev_item);
9319 * Post-subcommit or post-subabort cleanup for ON COMMIT management.
9321 * During subabort, we can immediately remove entries created during this
9322 * subtransaction. During subcommit, just relabel entries marked during
9323 * this subtransaction as being the parent's responsibility.
9326 AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
9327 SubTransactionId parentSubid)
9330 ListCell *prev_item;
9333 cur_item = list_head(on_commits);
9335 while (cur_item != NULL)
9337 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
9339 if (!isCommit && oc->creating_subid == mySubid)
9341 /* cur_item must be removed */
9342 on_commits = list_delete_cell(on_commits, cur_item, prev_item);
9345 cur_item = lnext(prev_item);
9347 cur_item = list_head(on_commits);
9351 /* cur_item must be preserved */
9352 if (oc->creating_subid == mySubid)
9353 oc->creating_subid = parentSubid;
9354 if (oc->deleting_subid == mySubid)
9355 oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
9356 prev_item = cur_item;
9357 cur_item = lnext(prev_item);