diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/tablecmds.c | 119 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 12 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 9 |
3 files changed, 134 insertions, 6 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c7b19124db1..13401ed107f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.66 2003/02/09 06:56:26 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.67 2003/02/13 05:19:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -2134,7 +2134,6 @@ AlterTableAlterColumnSetNotNull(Oid myrelid, bool recurse, heap_close(rel, NoLock); } - /* * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT */ @@ -2384,6 +2383,122 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse, heap_close(rel, NoLock); /* close rel, but keep lock! */ } +/* + * ALTER TABLE SET {WITHOUT} OIDS + */ +void +AlterTableAlterOids(Oid myrelid, bool recurse, bool setOid) +{ + Relation rel; + Relation class_rel; + HeapTuple tuple; + Form_pg_class tuple_class; + + rel = heap_open(myrelid, AccessExclusiveLock); + + if (rel->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", + RelationGetRelationName(rel)); + + if (!allowSystemTableMods + && IsSystemRelation(rel)) + elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", + RelationGetRelationName(rel)); + + if (!pg_class_ownercheck(myrelid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel)); + + + /* Get its pg_class tuple, too */ + class_rel = heap_openr(RelationRelationName, RowExclusiveLock); + + tuple = SearchSysCacheCopy(RELOID, + ObjectIdGetDatum(myrelid), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "ALTER TABLE: relation %u not found", myrelid); + tuple_class = (Form_pg_class) GETSTRUCT(tuple); + + /* Can we change the ownership of this tuple? */ + CheckTupleType(tuple_class); + + /* + * Okay, this is a valid tuple: check it's hasoids flag + * to see if we actually need to change anything + */ + if (tuple_class->relhasoids == setOid) + elog(ERROR, "ALTER TABLE: Table is already %s", + setOid ? "WITH OIDS" : "WITHOUT OIDS"); + + /* + * Propagate to children if desired + */ + if (recurse) + { + List *child, + *children; + + /* this routine is actually in the planner */ + children = find_all_inheritors(myrelid); + + /* + * find_all_inheritors does the recursive search of the + * inheritance hierarchy, so all we have to do is process all of + * the relids in the list that it returns. + */ + foreach(child, children) + { + Oid childrelid = lfirsti(child); + + if (childrelid == myrelid) + continue; + + AlterTableAlterOids(childrelid, false, setOid); + } + } + + + tuple_class->relhasoids = setOid; + simple_heap_update(class_rel, &tuple->t_self, tuple); + + /* Keep the catalog indexes up to date */ + CatalogUpdateIndexes(class_rel, tuple); + + + + if (setOid) + /* + * TODO: Generate the now required OID pg_attribute entry + */ + elog(ERROR, "ALTER TABLE WITH OIDS is unsupported"); + else + { + HeapTuple atttup; + Relation attrel; + + /* Add / Remove the oid record from pg_attribute */ + attrel = heap_open(RelOid_pg_attribute, RowExclusiveLock); + + /* + * Oids are being removed from the relation, so we need + * to remove the oid pg_attribute record relating. + */ + atttup = SearchSysCache(ATTNUM, + ObjectIdGetDatum(myrelid), + ObjectIdAttributeNumber, 0, 0); + if (!HeapTupleIsValid(atttup)) + elog(ERROR, "ALTER TABLE: relation %u doesn't have an Oid column to remove", myrelid); + + simple_heap_delete(attrel, &atttup->t_self); + + ReleaseSysCache(atttup); + + heap_close(attrel, NoLock); /* close rel, but keep lock! */ + } + + heap_close(rel, NoLock); /* close rel, but keep lock! */ + heap_close(class_rel, NoLock); /* close rel, but keep lock! */ +} /* * ALTER TABLE DROP COLUMN diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index ba153497826..f6ce850f37b 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.401 2003/02/10 04:44:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.402 2003/02/13 05:19:59 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1132,7 +1132,7 @@ AlterTableStmt: | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P { AlterTableStmt *n = makeNode(AlterTableStmt); - n->subtype = 'O'; + n->subtype = 'n'; n->relation = $3; n->name = $6; $$ = (Node *)n; @@ -1187,6 +1187,14 @@ AlterTableStmt: n->behavior = $7; $$ = (Node *)n; } + /* ALTER TABLE <relation> SET WITHOUT OIDS */ + | ALTER TABLE relation_expr SET WITHOUT OIDS + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; + n->subtype = 'o'; + $$ = (Node *)n; + } /* ALTER TABLE <name> CREATE TOAST TABLE */ | ALTER TABLE qualified_name CREATE TOAST TABLE { diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 18a474f34b6..b48550428f6 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.191 2003/02/10 04:44:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.192 2003/02/13 05:20:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -549,7 +549,7 @@ ProcessUtility(Node *parsetree, interpretInhOption(stmt->relation->inhOpt), stmt->name); break; - case 'O': /* ALTER COLUMN SET NOT NULL */ + case 'n': /* ALTER COLUMN SET NOT NULL */ AlterTableAlterColumnSetNotNull(relid, interpretInhOption(stmt->relation->inhOpt), stmt->name); @@ -611,6 +611,11 @@ ProcessUtility(Node *parsetree, AlterTableOwner(relid, get_usesysid(stmt->name)); break; + case 'o': /* ADD OIDS */ + AlterTableAlterOids(relid, + interpretInhOption(stmt->relation->inhOpt), + false); + break; default: /* oops */ elog(ERROR, "ProcessUtility: Invalid type for AlterTableStmt: %d", stmt->subtype); |