Trial implementation of ALTER DROP COLUMN.
authorHiroshi Inoue
Thu, 9 Mar 2000 05:00:26 +0000 (05:00 +0000)
committerHiroshi Inoue
Thu, 9 Mar 2000 05:00:26 +0000 (05:00 +0000)
They are #ifdef'd.
Add -D_DROP_COLUMN_HACK__ compile option
to evaluate it.

src/backend/commands/command.c
src/backend/commands/copy.c
src/backend/commands/vacuum.c
src/backend/optimizer/prep/preptlist.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/utils/cache/relcache.c
src/include/catalog/pg_attribute.h

index 620c601b17d0f916a05d64d6396ae3c3502144dc..b75f3840a879a819b2e541aac5b2a07d314e5421 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.69 2000/02/15 18:15:12 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.70 2000/03/09 05:00:23 inoue Exp $
  *
  * NOTES
  *   The PortalExecutorHeapMemory crap needs to be eliminated
 #include "utils/syscache.h"
 #include "utils/temprel.h"
 #include "commands/trigger.h"
+#ifdef _DROP_COLUMN_HACK__
+#include "catalog/pg_index.h"
+#include "catalog/pg_relcheck.h"
+#include "commands/defrem.h"
+#include "commands/comment.h"
+#include "access/genam.h"
+#include "optimizer/clauses.h"
+#include "../parser/parse.h"
+#endif /* _DROP_COLUMN_HACK__ */
 
 /* ----------------
  *     PortalExecutorHeapMemory stuff
@@ -668,6 +677,213 @@ drop_default(Oid relid, int16 attnum)
 }
 
 
+#ifdef _DROP_COLUMN_HACK__
+/*
+ * ALTER TABLE DROP COLUMN trial implementation
+ *     
+ */
+
+/*
+ * system table scan(index scan/sequential scan)
+ */
+typedef struct SysScanDescData
+{
+   Relation    heap_rel;
+   Relation    irel;
+   HeapScanDesc    scan;
+   IndexScanDesc   iscan;
+   HeapTupleData   tuple;
+   Buffer      buffer;
+} SysScanDescData, *SysScanDesc;
+   
+static void *
+systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey entry)
+{
+   bool    hasindex = (rel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
+   SysScanDesc sysscan;
+
+   sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
+   sysscan->heap_rel = rel;
+   sysscan->irel = (Relation) NULL;
+   sysscan->tuple.t_datamcxt = NULL;
+   sysscan->tuple.t_data = NULL;
+   sysscan->buffer = InvalidBuffer;
+   if (hasindex)
+   {
+       sysscan->irel = index_openr((char *)indexRelname);
+       sysscan->iscan = index_beginscan(sysscan->irel, false, nkeys, entry);
+   }
+   else
+       sysscan->scan = heap_beginscan(rel, false, SnapshotNow, nkeys, entry);
+   return (void *) sysscan;
+}
+static void
+systable_endscan(void *scan)
+{
+   SysScanDesc sysscan = (SysScanDesc) scan;
+
+   if (sysscan->irel)
+   {
+       if (BufferIsValid(sysscan->buffer))
+           ReleaseBuffer(sysscan->buffer);
+       index_endscan(sysscan->iscan);
+       index_close(sysscan->irel);
+   }
+   else
+       heap_endscan(sysscan->scan);
+   pfree(scan);
+}
+static HeapTuple
+systable_getnext(void *scan)
+{
+   SysScanDesc sysscan = (SysScanDesc) scan;
+   HeapTuple   htup = (HeapTuple) NULL;
+   RetrieveIndexResult indexRes;
+
+   if (sysscan->irel)
+   {
+       if (BufferIsValid(sysscan->buffer))
+       {
+           ReleaseBuffer(sysscan->buffer);
+           sysscan->buffer = InvalidBuffer;
+       }
+       while (indexRes = index_getnext(sysscan->iscan, ForwardScanDirection), indexRes != NULL)
+       {
+           sysscan->tuple.t_self = indexRes->heap_iptr;
+           heap_fetch(sysscan->heap_rel, SnapshotNow, &sysscan->tuple, &(sysscan->buffer));
+           pfree(indexRes);
+           if (sysscan->tuple.t_data != NULL)
+           {
+               htup = &sysscan->tuple;
+               break;
+           }
+       }
+   }
+   else
+       htup = heap_getnext(sysscan->scan, 0);
+   return htup;
+}
+
+/*
+ * find a specified attribute in a node entry
+ */
+static bool
+find_attribute_walker(Node *node, int attnum)
+{
+   if (node == NULL)
+       return false;
+   if (IsA(node, Var))
+   {
+       Var *var = (Var *) node;
+       if (var->varlevelsup == 0 && var->varno == 1 &&
+           var->varattno == attnum)
+           return true;
+   }
+   return expression_tree_walker(node, find_attribute_walker, (void *)attnum); 
+}
+static bool
+find_attribute_in_node(Node *node, int attnum)
+{
+   return  expression_tree_walker(node, find_attribute_walker, (void *)attnum);
+}
+/*
+ * Remove/check references for the column
+ */
+static bool
+RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
+{
+   Relation    indexRelation, rcrel;
+   ScanKeyData entry;
+   HeapScanDesc    scan;
+   void        *sysscan;
+   HeapTuple   htup, indexTuple;
+   Form_pg_index   index;
+   Form_pg_relcheck    relcheck;
+   Form_pg_class   pgcform = (Form_pg_class) NULL;
+   int     i;
+   bool        checkok = true;
+
+   
+   if (!checkonly)
+       pgcform = (Form_pg_class) GETSTRUCT (reltup);
+   /*
+    *  Remove/check constraints here
+    */
+   ScanKeyEntryInitialize(&entry, (bits16) 0x0, Anum_pg_relcheck_rcrelid,
+           (RegProcedure) F_OIDEQ, ObjectIdGetDatum(reloid));
+   rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
+   sysscan = systable_beginscan(rcrel, RelCheckIndex,1 ,&entry);
+
+   while (HeapTupleIsValid(htup = systable_getnext(sysscan)))
+   {
+       char    *ccbin;
+       Node    *node;
+
+       relcheck = (Form_pg_relcheck) GETSTRUCT(htup);
+       ccbin = textout(&relcheck->rcbin);
+       if (!ccbin)
+           continue;
+       node = stringToNode(ccbin);
+       pfree(ccbin);
+       if (find_attribute_in_node(node, attnum))
+       {
+           if (checkonly)
+           {
+               checkok = false;
+               elog(ERROR, "target column is used in a constraint");
+           }
+           else
+           {
+               heap_delete(rcrel, &htup->t_self, NULL);
+               pgcform->relchecks--;
+           }
+       }
+   }
+   systable_endscan(sysscan);
+   heap_close(rcrel, NoLock);
+
+   /*
+    *  What to do with triggers/rules/views/procedues ?
+    */
+
+   /*
+    *  Remove/check indexes
+    */
+   indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
+   ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
+               ObjectIdGetDatum(reloid));
+   scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
+   while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
+   {
+       index = (Form_pg_index) GETSTRUCT(indexTuple);
+       for (i = 0; i < INDEX_MAX_KEYS; i++)
+       {
+           if (index->indkey[i] == InvalidAttrNumber)
+               break;
+           else if (index->indkey[i] == attnum)
+           {
+               if (checkonly)
+               {
+                   checkok = false;
+                   elog(ERROR, "target column is used in an index");
+               }
+               else
+               {
+                   htup = SearchSysCacheTuple(RELOID,
+                       ObjectIdGetDatum(index->indexrelid),
+                       0, 0, 0); 
+                   RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
+               }
+               break;
+           }
+       }
+   }
+   heap_endscan(scan);
+   heap_close(indexRelation, NoLock);
+
+   return checkok;
+}
+#endif /* _DROP_COLUMN_HACK__ */
 
 /*
  * ALTER TABLE DROP COLUMN
@@ -677,7 +893,170 @@ AlterTableDropColumn(const char *relationName,
                      bool inh, const char *colName,
                      int behavior)
 {
+#ifdef _DROP_COLUMN_HACK__
+   Relation    rel, attrdesc, adrel;
+   Oid     myrelid, attoid;
+   HeapTuple   reltup;
+   HeapTupleData   classtuple;
+   Buffer      buffer;
+   Form_pg_attribute attribute;
+   HeapTuple   tup;
+   Relation    idescs[Num_pg_attr_indices];
+   int     attnum;
+   bool        hasindex;
+   char        dropColname[32];
+   void        *sysscan;
+       ScanKeyData scankeys[2];
+
+   if (inh)    
+       elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
+   /*
+    * permissions checking.  this would normally be done in utility.c,
+    * but this particular routine is recursive.
+    *
+    * normally, only the owner of a class can change its schema.
+    */
+   if (!allowSystemTableMods && IsSystemRelationName(relationName))
+       elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+            relationName);
+#ifndef NO_SECURITY
+   if (!pg_ownercheck(UserName, relationName, RELNAME))
+       elog(ERROR, "ALTER TABLE: permission denied");
+#endif
+
+   /*
+    * Grab an exclusive lock on the target table, which we will NOT release
+    * until end of transaction.
+    */
+   rel = heap_openr(relationName, AccessExclusiveLock);
+   myrelid = RelationGetRelid(rel);
+   heap_close(rel, NoLock);    /* close rel but keep lock! */
+
+   /*
+    *  What to do when rel has inheritors ?
+    */
+   if (length(find_all_inheritors(myrelid)) > 1)
+       elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from");
+
+
+   /*
+    *  lock the pg_class tuple for update
+    */
+   reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName),
+                           0, 0, 0);
+
+   if (!HeapTupleIsValid(reltup))
+       elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
+            relationName);
+   rel = heap_openr(RelationRelationName, RowExclusiveLock);
+   classtuple.t_self = reltup->t_self;
+   switch (heap_mark4update(rel, &classtuple, &buffer))
+   {
+       case HeapTupleSelfUpdated:
+       case HeapTupleMayBeUpdated:
+           break;
+       default:
+           elog(ERROR, "couldn't lock pg_class tuple");
+   }
+   reltup = heap_copytuple(&classtuple);
+   ReleaseBuffer(buffer);
+
+   /*
+    * XXX is the following check sufficient?
+    */
+   if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
+   {
+       elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
+            relationName);
+   }
+
+   attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
+
+   /*
+    * Get the target pg_attribute tuple
+    */
+   tup = SearchSysCacheTupleCopy(ATTNAME,
+               ObjectIdGetDatum(reltup->t_data->t_oid),
+               PointerGetDatum(colName), 0, 0);
+   if (!HeapTupleIsValid(tup))
+       elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
+                colName, relationName);
+
+   attribute = (Form_pg_attribute) GETSTRUCT(tup);
+   if (attribute->attnum <= 0)
+       elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName);
+   attnum = attribute->attnum;
+   attoid = tup->t_data->t_oid;
+   /*
+    *  Check constraints/indices etc here
+    */
+   if (behavior != CASCADE)
+   {
+       if (!RemoveColumnReferences(myrelid, attnum, true, NULL))
+           elog(ERROR, "the column is referenced");
+   }
+
+   /*
+    *  change the target pg_attribute tuple
+    */
+   sprintf(dropColname, "*already Dropped*%d", attnum);
+   namestrcpy(&(attribute->attname), dropColname);
+   ATTRIBUTE_DROP_COLUMN(attribute);
+
+   heap_update(attrdesc, &tup->t_self, tup, NULL);
+   hasindex = (!IsIgnoringSystemIndexes() && RelationGetForm(attrdesc)->relhasindex);
+   if (hasindex)
+   {
+       CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+       CatalogIndexInsert(idescs, Num_pg_attr_indices,
+               attrdesc, tup);
+       CatalogCloseIndices(Num_pg_attr_indices, idescs);
+   }
+   heap_close(attrdesc, NoLock);
+   heap_freetuple(tup);
+
+   /* delete comments */
+   DeleteComments(attoid);
+   /* delete attrdef */
+   adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
+   ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid,
+           F_OIDEQ, ObjectIdGetDatum(myrelid));
+   /* Oops pg_attrdef doesn't have (adrelid,adnum) index
+   ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
+           F_INT2EQ, Int16GetDatum(attnum));
+   sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
+   */
+   sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys);
+   while (HeapTupleIsValid(tup = systable_getnext(sysscan)))
+   { 
+       if (((Form_pg_attrdef) GETSTRUCT(tup))->adnum == attnum)
+       {
+           heap_delete(adrel, &tup->t_self, NULL);
+           break;
+       }
+   }
+   systable_endscan(sysscan);
+   heap_close(adrel, NoLock);
+   /*
+    *  Remove objects which reference this column
+    */
+   if (behavior == CASCADE)
+   {
+       Relation    ridescs[Num_pg_class_indices];
+
+       RemoveColumnReferences(myrelid, attnum, false, reltup);
+       /* update pg_class tuple */
+       heap_update(rel, &reltup->t_self, reltup, NULL);
+       CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+       CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, reltup);
+       CatalogCloseIndices(Num_pg_class_indices, ridescs);
+   }
+
+   heap_freetuple(reltup);
+   heap_close(rel, NoLock);
+#else
     elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented");
+#endif /* _DROP_COLUMN_HACK__ */
 }
 
 
index 85a50c103988345bbc48aefb020cd620961fca4c..a91072522a5319b9eb20bf0187b32e164fe8e138 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.101 2000/02/13 18:59:50 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.102 2000/03/09 05:00:23 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -394,6 +394,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
 
    int32       attr_count,
                i;
+#ifdef _DROP_COLUMN_HACK__
+   bool        *valid;
+#endif /* _DROP_COLUMN_HACK__ */
    Form_pg_attribute *attr;
    FmgrInfo   *out_functions;
    Oid         out_func_oid;
@@ -425,8 +428,20 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
        out_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));
        elements = (Oid *) palloc(attr_count * sizeof(Oid));
        typmod = (int32 *) palloc(attr_count * sizeof(int32));
+#ifdef _DROP_COLUMN_HACK__
+       valid = (bool *) palloc(attr_count * sizeof(bool));
+#endif /* _DROP_COLUMN_HACK__ */
        for (i = 0; i < attr_count; i++)
        {
+#ifdef _DROP_COLUMN_HACK__
+           if (COLUMN_IS_DROPPED(attr[i]))
+           {
+               valid[i] = false;
+               continue;
+           }
+           else
+               valid[i] = true;
+#endif /* _DROP_COLUMN_HACK__ */
            out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid);
            fmgr_info(out_func_oid, &out_functions[i]);
            elements[i] = GetTypeElement(attr[i]->atttypid);
@@ -466,6 +481,14 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
            value = heap_getattr(tuple, i + 1, tupDesc, &isnull);
            if (!binary)
            {
+#ifdef _DROP_COLUMN_HACK__
+               if (!valid[i])
+               {
+                   if (i == attr_count - 1)
+                       CopySendChar('\n', fp);
+                   continue;
+               }
+#endif /* _DROP_COLUMN_HACK__ */
                if (!isnull)
                {
                    string = (char *) (*fmgr_faddr(&out_functions[i]))
@@ -692,6 +715,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
        typmod = (int32 *) palloc(attr_count * sizeof(int32));
        for (i = 0; i < attr_count; i++)
        {
+#ifdef _DROP_COLUMN_HACK__
+           if (COLUMN_IS_DROPPED(attr[i]))
+               continue;
+#endif /* _DROP_COLUMN_HACK__ */
            in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
            fmgr_info(in_func_oid, &in_functions[i]);
            elements[i] = GetTypeElement(attr[i]->atttypid);
@@ -718,6 +745,13 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
    {
        nulls[i] = ' ';
        index_nulls[i] = ' ';
+#ifdef _DROP_COLUMN_HACK__
+       if (COLUMN_IS_DROPPED(attr[i]))
+       {
+           byval[i] = 'n';
+           continue;
+       }
+#endif /* _DROP_COLUMN_HACK__ */
        byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
    }
 
@@ -750,6 +784,14 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
            }
            for (i = 0; i < attr_count && !done; i++)
            {
+#ifdef _DROP_COLUMN_HACK__
+               if (COLUMN_IS_DROPPED(attr[i]))
+               {
+                   values[i] = PointerGetDatum(NULL);
+                   nulls[i] = 'n';
+                   continue;
+               }
+#endif /* _DROP_COLUMN_HACK__ */
                string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print);
                if (isnull)
                {
index 3cd9b026519fe2f0b8b0baa9604cd70fe42cd08f..f86c5bc1e22a7ed193e800434b6ecd25cf9eddee 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.142 2000/03/08 23:41:00 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.143 2000/03/09 05:00:23 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2240,6 +2240,10 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple)
        VacAttrStats *stats = &vacattrstats[i];
        bool        value_hit = true;
 
+#ifdef _DROP_COLUMN_HACK__
+       if (COLUMN_IS_DROPPED(stats->attr))
+           continue;
+#endif /* _DROP_COLUMN_HACK__ */
        value = heap_getattr(tuple,
                             stats->attr->attnum, tupDesc, &isnull);
 
index 8c6c2ceb8d98c4bed6910f72fd81909d112971f3..22ed6f418f79a42dba35af1c602b3236a5e4913c 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.34 2000/01/26 05:56:39 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.35 2000/03/09 05:00:24 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -189,10 +189,20 @@ expand_targetlist(List *tlist, int command_type,
            {
                case CMD_INSERT:
                {
+#ifdef _DROP_COLUMN_HACK__
+                   Datum       typedefault;
+#else
                    Datum       typedefault = get_typdefault(atttype);
+#endif /* _DROP_COLUMN_HACK__ */
                    int         typlen;
                    Const      *temp_const;
 
+#ifdef _DROP_COLUMN_HACK__
+                   if (COLUMN_IS_DROPPED(att_tup))
+                       typedefault = PointerGetDatum(NULL);
+                   else
+                       typedefault = get_typdefault(atttype);
+#endif /* _DROP_COLUMN_HACK__ */
                    if (typedefault == PointerGetDatum(NULL))
                        typlen = 0;
                    else
@@ -230,8 +240,25 @@ expand_targetlist(List *tlist, int command_type,
                {
                    Var        *temp_var;
 
+#ifdef _DROP_COLUMN_HACK__
+                   Node    *temp_node = (Node *) NULL;
+                   if (COLUMN_IS_DROPPED(att_tup))
+                   {
+                       temp_node = (Node *)makeConst(atttype,                              0, 
+                           PointerGetDatum(NULL),
+                               true,
+                               false,
+                               false, /* not a set */
+                               false);
+                   }
+                   else
+#endif /* _DROP_COLUMN_HACK__ */
                    temp_var = makeVar(result_relation, attrno, atttype,
                                       atttypmod, 0);
+#ifdef _DROP_COLUMN_HACK__
+                   if (!temp_node)
+                       temp_node = (Node *) temp_var;
+#endif /* _DROP_COLUMN_HACK__ */
 
                    new_tle = makeTargetEntry(makeResdom(attrno,
                                                         atttype,
@@ -239,8 +266,12 @@ expand_targetlist(List *tlist, int command_type,
                                                         pstrdup(attrname),
                                                         0,
                                                         (Oid) 0,
-                                                        false),
-                                             (Node *) temp_var);
+                                                        false),                                        
+#ifdef _DROP_COLUMN_HACK__
+               temp_node);
+#else
+   (Node *) temp_var);
+#endif /* _DROP_COLUMN_HACK__ */
                    break;
                }
                default:
index 02a3cd2de092b8e023ab462a227062670458c05b..265642faaf39adc3f78c17362170aa2d6efa9f7a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.35 2000/02/15 03:37:47 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.36 2000/03/09 05:00:24 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -359,6 +359,10 @@ expandTable(ParseState *pstate, char *refname, bool getaliases)
    {
        char       *attrname;
 
+#ifdef _DROP_COLUMN_HACK__
+       if (COLUMN_IS_DROPPED(rel->rd_att->attrs[varattno]))
+           continue;
+#endif /* _DROP_COLUMN_HACK__ */
        attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
        attr->attrs = lappend(attr->attrs, makeString(attrname));
    }
@@ -404,6 +408,10 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno)
        Var            *varnode;
        TargetEntry    *te = makeNode(TargetEntry);
 
+#ifdef _DROP_COLUMN_HACK__
+       if (COLUMN_IS_DROPPED(rel->rd_att->attrs[varattno]))
+           continue;
+#endif /* _DROP_COLUMN_HACK__ */
        attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
 
        /* varattno is zero-based, so check that length() is always greater */
index 9d00e1789e1cec855300e03266980208e275b37e..e815efc9639b74f0a49ff58801bd96a4a83fd08a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.55 2000/02/15 03:37:47 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.56 2000/03/09 05:00:24 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -355,6 +355,12 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
        {
            Ident      *id = makeNode(Ident);
 
+#ifdef _DROP_COLUMN_HACK__
+           if (COLUMN_IS_DROPPED(attr[i]))
+           {
+               continue;
+           }
+#endif /* _DROP_COLUMN_HACK__ */
            id->name = palloc(NAMEDATALEN);
            StrNCpy(id->name, NameStr(attr[i]->attname), NAMEDATALEN);
            id->indirection = NIL;
index 74bcb10c69efe87b73ec82660d37eeda935d4193..11ab6c750fd8f0a694bab52d7ebb8a296b109da4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.91 2000/02/27 12:02:32 wieck Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.92 2000/03/09 05:00:25 inoue Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -568,6 +568,9 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
    AttrDefault *attrdef = NULL;
    int         ndef = 0;
    int         i;
+#ifdef _DROP_COLUMN_HACK__
+   bool            columnDropped;
+#endif /* _DROP_COLUMN_HACK__ */
 
    constr->has_not_null = false;
 
@@ -575,12 +578,25 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
 
    for (i = 1; i <= relation->rd_rel->relnatts; i++)
    {
+#ifdef _DROP_COLUMN_HACK__
+       columnDropped = false;
+#endif /* _DROP_COLUMN_HACK__ */
        atttup = (HeapTuple) AttributeRelidNumIndexScan(attrel,
                                          RelationGetRelid(relation), i);
 
        if (!HeapTupleIsValid(atttup))
+#ifdef _DROP_COLUMN_HACK__
+       {
+           atttup = (HeapTuple) AttributeRelidNumIndexScan(attrel,
+                                                   RelationGetRelid(relation), DROPPED_COLUMN_INDEX(i));
+           if (!HeapTupleIsValid(atttup))
+#endif /* _DROP_COLUMN_HACK__ */
            elog(ERROR, "cannot find attribute %d of relation %s", i,
                 RelationGetRelationName(relation));
+#ifdef _DROP_COLUMN_HACK__
+           columnDropped = true;
+       }
+#endif /* _DROP_COLUMN_HACK__ */
        attp = (Form_pg_attribute) GETSTRUCT(atttup);
 
        relation->rd_att->attrs[i - 1] =
@@ -590,6 +606,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
                (char *) attp,
                ATTRIBUTE_TUPLE_SIZE);
 
+#ifdef _DROP_COLUMN_HACK__
+       if (columnDropped)
+           continue;
+#endif /* _DROP_COLUMN_HACK__ */
        /* Update if this attribute have a constraint */
        if (attp->attnotnull)
            constr->has_not_null = true;
index d7a1adb1c6a6725c7a823d74cb85b6fbab8dafd8..54f3adc9ee1dfc9c31462e4450a926a2094917e3 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_attribute.h,v 1.53 2000/01/26 05:57:57 momjian Exp $
+ * $Id: pg_attribute.h,v 1.54 2000/03/09 05:00:26 inoue Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -178,6 +178,20 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 #define Anum_pg_attribute_atthasdef        15
 
 
+#ifdef _DROP_COLUMN_HACK__
+/*
+ * CONSTANT and MACROS for DROP COLUMN implementation
+ */
+#define    DROP_COLUMN_OFFSET  -20
+#define    COLUMN_IS_DROPPED(attribute)    ((attribute)->attnum <= DROP_COLUMN_OFFSET)
+#define    DROPPED_COLUMN_INDEX(attidx)    (DROP_COLUMN_OFFSET - attidx)
+#define    ATTRIBUTE_DROP_COLUMN(attribute) \
+   Assert((attribute)->attnum > 0); \
+   (attribute)->attnum = DROPPED_COLUMN_INDEX((attribute)->attnum); \
+   (attribute)->atttypid = (Oid) -1; \
+   (attribute)->attnotnull = false; \
+   (attribute)->atthasdef = false; 
+#endif /* _DROP_COLUMN_HACK__ */
 /* ----------------
  *     SCHEMA_ macros for declaring hardcoded tuple descriptors.
  *     these are used in utils/cache/relcache.c