Code for WITHOUT OIDS.
authorBruce Momjian <bruce@momjian.us>
Thu, 13 Feb 2003 05:20:05 +0000 (05:20 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 13 Feb 2003 05:20:05 +0000 (05:20 +0000)
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>

doc/src/sgml/ref/alter_table.sgml
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/tablecmds.h
src/include/nodes/parsenodes.h
src/test/regress/expected/alter_table.out
src/test/regress/sql/alter_table.sql

index 2287a72cb65c9572b4a345b4fa25fabe04fe444e..5499cd158cc8ed75cac65b0d701063dd0ca2c3c0 100644 (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>
index c7b19124db1c267eb2d4bf131282ccce7a8c948b..13401ed107fb93ee16bb7dd123dcb7a467e6bc15 100644 (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
index ba153497826f383005aa31091218d9d296d13a57..f6ce850f37ba8400268905a741e1d4c5f11da4df 100644 (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
                                {
index 18a474f34b6863140acf7715c355d876cc176611..b48550428f65a44899a7c90cd1081b7f75985894 100644 (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);
index 13873dad1b52d220c298fd8bbe7cc89e324eee8a..6b533cab2fc91ea0c205acff404226363da73f54 100644 (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);
index 5f8f4794f936ef3bcf092844bed262dfee91bc4a..9474bc6490b3a69d9db8f48b7d3c26360a8a7d42 100644 (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 */
index 877d8bdd84bdb1aa27789ca268a35aa5082274f1..7015753d173fd457c28f3b31f0d75da5519caa3f 100644 (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);
index 79ea952adeefb2f15e1e52181756abaa6a0ca9f9..8e98d077a4a4724d114e49c86105c172883a274c 100644 (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);