<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.54 2003/01/19 00:13:29 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.55 2003/02/13 05:19:59 momjian Exp $
PostgreSQL documentation
-->
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
+ SET WITHOUT OIDS
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable
class="PARAMETER">new_column</replaceable>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>SET WITHOUT OIDS</term>
+ <listitem>
+ <para>
+ Removes the <literal>OID</literal> column from the the table. Removing (setting without)
+ oids from a table also do not occur immediately. The space an <literal>OID</literal>
+ uses will be reclaimed when the tuple is updated. Without updating the tuple, both the
+ space and the value of the <literal>OID</literal> are maintained indefinitely. This is
+ semantically similar to the <literal>DROP COLUMN</literal> process.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>RENAME</term>
<listitem>
<para>
- The <literal>RENAME</literal> forms change the name of a table
+ The <literal>RENAME</literal> forms change the name of a table
(or an index, sequence, or view) or the name of an individual column in
a table. There is no effect on the stored data.
</para>
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
heap_close(rel, NoLock);
}
-
/*
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
*/
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
*
*
* 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
| 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;
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
{
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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);
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: tablecmds.h,v 1.10 2002/11/11 22:19:24 tgl Exp $
+ * $Id: tablecmds.h,v 1.11 2003/02/13 05:20:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern void AlterTableOwner(Oid relationOid, int32 newOwnerSysId);
+extern void AlterTableAlterOids(Oid myrelid, bool recurse, bool setOid);
+
extern Oid DefineRelation(CreateStmt *stmt, char relkind);
extern void RemoveRelation(const RangeVar *relation, DropBehavior behavior);
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.229 2003/02/10 04:44:47 tgl Exp $
+ * $Id: parsenodes.h,v 1.230 2003/02/13 05:20:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* A = add column
* T = alter column default
* N = alter column drop not null
- * O = alter column set not null
+ * n = alter column set not null
* S = alter column statistics
* M = alter column storage
* D = drop column
* X = drop constraint
* E = create toast table
* U = change owner
+ * o = DROP OIDS
*------------
*/
RangeVar *relation; /* table to work on */
drop table p1, p2 cascade;
NOTICE: Drop cascades to table c1
NOTICE: Drop cascades to table gc1
+--
+-- Test the ALTER TABLE WITHOUT OIDS command
+--
+create table altstartwith (col integer) with oids;
+insert into altstartwith values (1);
+select oid > 0, * from altstartwith;
+ ?column? | col
+----------+-----
+ t | 1
+(1 row)
+
+alter table altstartwith set without oids;
+select oid > 0, * from altstartwith; -- fails
+ERROR: Attribute "oid" not found
+select * from altstartwith;
+ col
+-----
+ 1
+(1 row)
+
+-- Run inheritance tests
+create table altwithoid (col integer) with oids;
+-- Inherits parents oid column
+create table altinhoid () inherits (altwithoid) without oids;
+insert into altinhoid values (1);
+select oid > 0, * from altwithoid;
+ ?column? | col
+----------+-----
+ t | 1
+(1 row)
+
+select oid > 0, * from altinhoid;
+ ?column? | col
+----------+-----
+ t | 1
+(1 row)
+
+alter table altwithoid set without oids;
+alter table altinhoid set without oids; -- fails
+ERROR: ALTER TABLE: Table is already WITHOUT OIDS
+select oid > 0, * from altwithoid; -- fails
+ERROR: Attribute "oid" not found
+select oid > 0, * from altinhoid; -- fails
+ERROR: Attribute "oid" not found
+select * from altwithoid;
+ col
+-----
+ 1
+(1 row)
+
+select * from altinhoid;
+ col
+-----
+ 1
+(1 row)
+
-- test renumbering of child-table columns in inherited operations
create table p1 (f1 int);
create table c1 (f2 text, f3 int) inherits (p1);
drop table p1, p2 cascade;
+--
+-- Test the ALTER TABLE WITHOUT OIDS command
+--
+create table altstartwith (col integer) with oids;
+
+insert into altstartwith values (1);
+
+select oid > 0, * from altstartwith;
+
+alter table altstartwith set without oids;
+
+select oid > 0, * from altstartwith; -- fails
+select * from altstartwith;
+
+-- Run inheritance tests
+create table altwithoid (col integer) with oids;
+
+-- Inherits parents oid column
+create table altinhoid () inherits (altwithoid) without oids;
+
+insert into altinhoid values (1);
+
+select oid > 0, * from altwithoid;
+select oid > 0, * from altinhoid;
+
+alter table altwithoid set without oids;
+alter table altinhoid set without oids; -- fails
+
+select oid > 0, * from altwithoid; -- fails
+select oid > 0, * from altinhoid; -- fails
+select * from altwithoid;
+select * from altinhoid;
+
-- test renumbering of child-table columns in inherited operations
create table p1 (f1 int);