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

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 @@
 
 
@@ -33,6 +33,8 @@ ALTER TABLE [ ONLY ] table [ * ]
     ALTER [ COLUMN ] column SET STATISTICS integer
 ALTER TABLE [ ONLY ] table [ * ]
     ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ALTER TABLE [ ONLY ] table [ * ]
+    SET WITHOUT OIDS
 ALTER TABLE [ ONLY ] table [ * ]
     RENAME [ COLUMN ] column TO 
     class="PARAMETER">new_column
@@ -286,11 +288,24 @@ ALTER TABLE table
     
    
 
+   
+    SET WITHOUT OIDS
+    
+     
+      Removes the OID column from the the table.  Removing (setting without)
+      oids from a table also do not occur immediately.  The space an OID
+      uses will be reclaimed when the tuple is updated.  Without updating the tuple, both the
+      space and the value of the OID are maintained indefinitely.  This is
+      semantically similar to the DROP COLUMN process.
+     
+    
+   
+
    
     RENAME
     
      
-      The RENAME forms change the name of  a table
+      The RENAME 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.
      
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  SET WITHOUT OIDS  */
+           | ALTER TABLE relation_expr SET WITHOUT OIDS
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->relation = $3;
+                   n->subtype = 'o';
+                   $$ = (Node *)n;
+               }
            /* ALTER TABLE  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);