Code for WITHOUT OIDS.

On Wed, 2003-01-08 at 21:59, Christopher Kings-Lynne wrote:
> I agree.  I want to remove OIDs from heaps of our tables when we go to 7.3.
> I'd rather not have to do it in the dump due to down time.


Rod Taylor <rbt@rbt.ca>
This commit is contained in:
Bruce Momjian 2003-02-13 05:20:05 +00:00
parent 8add2e1bca
commit 8195f8f042
8 changed files with 246 additions and 11 deletions

View File

@ -1,5 +1,5 @@
<!--
$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
-->
@ -33,6 +33,8 @@ ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
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>
@ -286,11 +288,24 @@ ALTER TABLE <replaceable class="PARAMETER">table</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>

View File

@ -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

View File

@ -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
{

View File

@ -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);

View File

@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -47,6 +47,8 @@ extern void AlterTableCreateToastTable(Oid relOid, bool silent);
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);

View File

@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -698,7 +698,7 @@ typedef struct AlterTableStmt
* 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
@ -708,6 +708,7 @@ typedef struct AlterTableStmt
* X = drop constraint
* E = create toast table
* U = change owner
* o = DROP OIDS
*------------
*/
RangeVar *relation; /* table to work on */

View File

@ -1179,6 +1179,62 @@ order by relname, attnum;
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);

View File

@ -850,6 +850,39 @@ order by relname, attnum;
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);