diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 119 |
1 files changed, 117 insertions, 2 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 |