OSDN Git Service

Trial implementation of ALTER DROP COLUMN.
authorHiroshi Inoue <inoue@tpf.co.jp>
Thu, 9 Mar 2000 05:00:26 +0000 (05:00 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
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 620c601..b75f384 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 85a50c1..a910725 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 3cd9b02..f86c5bc 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 8c6c2ce..22ed6f4 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 02a3cd2..265642f 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 9d00e17..e815efc 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 74bcb10..11ab6c7 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 d7a1adb..54f3adc 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