Remove DEFAULT/CHECK infos from catalog on DROP TABLE
authorVadim B. Mikheev
Fri, 22 Aug 1997 14:10:26 +0000 (14:10 +0000)
committerVadim B. Mikheev
Fri, 22 Aug 1997 14:10:26 +0000 (14:10 +0000)
Store CHECK infos on CREATE TABLE

src/backend/catalog/heap.c
src/backend/catalog/index.c

index 5f3be132c5223c314bf0891c05ba9b4870075550..7899f6c0007b372eae76ea1a143e06d1b4a31b68 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.21 1997/08/22 02:58:51 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.22 1997/08/22 14:10:24 vadim Exp $
  *
  * INTERFACE ROUTINES
  * heap_creatr()       - Create an uncataloged heap relation
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifndef HAVE_MEMMOVE
 # include 
 #else
@@ -68,8 +69,7 @@ static void RelationRemoveInheritance(Relation relation);
 static void RemoveFromTempRelList(Relation r);
 static void addNewRelationType(char *typeName, Oid new_rel_oid);
 static void StoreConstraints (Relation rel);
-static void StoreAttrDefault (Relation rel, AttrDefault *attrdef);
-static void StoreRelCheck (Relation rel, ConstrCheck *check);
+static void RemoveConstraints (Relation rel);
 
 
 /* ----------------------------------------------------------------
@@ -371,8 +371,10 @@ heap_creatr(char *name,
  *
  * 6) AddPgRelationTuple() is called to register the
  *    relation itself in the catalogs.
+ * 
+ * 7) StoreConstraints is called ()    - vadim 08/22/97
  *
- * 7) the relations are closed and the new relation's oid
+ * 8) the relations are closed and the new relation's oid
  *    is returned.
  *
  * old comments:
@@ -847,7 +849,8 @@ heap_create(char relname[],
  * 4)  remove pg_class tuple
  * 5)  remove pg_attribute tuples
  * 6)  remove pg_type tuples
- * 7)  unlink relation
+ * 7)  RemoveConstraints ()
+ * 8)  unlink relation
  *
  * old comments
  * Except for vital relations, removes relation from
@@ -1327,6 +1330,8 @@ heap_destroy(char *relname)
      * Does nothing!!! Flushing moved below.   - vadim 06/04/97
     RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
      */
+    
+    RemoveConstraints (rdesc);
 
     /* ----------------
      * unlink the relation and finish up.
@@ -1468,30 +1473,6 @@ DestroyTempRels(void)
     tempRels = NULL;
 }
 
-static void 
-StoreConstraints (Relation rel)
-{
-    TupleConstr *constr = rel->rd_att->constr;
-    int i;
-    
-    if ( !constr )
-       return;
-    
-    if ( constr->num_defval > 0 )
-    {
-       for (i = 0; i < constr->num_defval; i++)
-           StoreAttrDefault (rel, &(constr->defval[i]));
-    }
-    
-    if ( constr->num_check > 0 )
-    {
-       for (i = 0; i < constr->num_check; i++)
-           StoreRelCheck (rel, &(constr->check[i]));
-    }
-    
-    return;
-}
-
 extern List *flatten_tlist(List *tlist);
 extern List *pg_plan(char *query_string, Oid *typev, int nargs,                
                      QueryTreeList **queryListP, CommandDest dest);            
@@ -1520,12 +1501,14 @@ StoreAttrDefault (Relation rel, AttrDefault *attrdef)
 start:;
     sprintf (str, "select %s%s from %.*s", attrdef->adsrc, cast,
            NAMEDATALEN, rel->rd_rel->relname.data);
+    setheapoverride(true);
     planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
+    setheapoverride(false);
     query = (Query*) (queryTree_list->qtrees[0]);
     
     if ( length (query->rtable) > 1 || 
            flatten_tlist (query->targetList) != NIL )
-       elog (WARN, "AttributeDefault: cannot use attribute(s)");
+       elog (WARN, "DEFAULT: cannot use attribute(s)");
     te = (TargetEntry *) lfirst (query->targetList);
     resdom = te->resdom;
     expr = te->expr;
@@ -1535,13 +1518,13 @@ start:;
        if ( ((Const*)expr)->consttype != atp->atttypid )
        {
            if ( *cast != 0 )
-               elog (WARN, "AttributeDefault: casting failed - const type mismatched");
+               elog (WARN, "DEFAULT: const type mismatched");
            sprintf (cast, ":: %s", get_id_typname (atp->atttypid));
            goto start;
        }
     }
     else if ( exprType (expr) != atp->atttypid )
-       elog (WARN, "AttributeDefault: type mismatched");
+       elog (WARN, "DEFAULT: type mismatched");
     
     adbin = nodeToString (expr);
     oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
@@ -1560,6 +1543,7 @@ start:;
     heap_insert (adrel, tuple);
     CatalogIndexInsert (idescs, Num_pg_attrdef_indices, adrel, tuple);
     CatalogCloseIndices (Num_pg_attrdef_indices, idescs);
+    heap_close (adrel);
     
     pfree (DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
     pfree (DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
@@ -1570,6 +1554,153 @@ start:;
 static void 
 StoreRelCheck (Relation rel, ConstrCheck *check)
 {
+    char str[MAX_PARSE_BUFFER];
+    QueryTreeList *queryTree_list;
+    Query *query;
+    List *planTree_list;
+    Plan *plan;
+    List *qual;
+    char *ccbin;
+    MemoryContext oldcxt;
+    Relation rcrel;
+    Relation idescs[Num_pg_relcheck_indices];
+    HeapTuple tuple;
+    Datum values[4];
+    char nulls[4] = {' ', ' ', ' ', ' '};
+    extern GlobalMemory    CacheCxt;
+    
+    sprintf (str, "select 1 from %.*s where %s", 
+           NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
+    setheapoverride(true);
+    planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
+    setheapoverride(false);
+    query = (Query*) (queryTree_list->qtrees[0]);
+    
+    if ( length (query->rtable) > 1 )
+       elog (WARN, "CHECK: only relation %.*s can be referenced",
+           NAMEDATALEN, rel->rd_rel->relname.data);
+    
+    plan = (Plan*) lfirst(planTree_list);
+    qual = plan->qual;
+    
+    ccbin = nodeToString (qual);
+    oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
+    check->ccbin = (char*) palloc (strlen (ccbin) + 1);
+    strcpy (check->ccbin, ccbin);
+    (void) MemoryContextSwitchTo (oldcxt);
+    pfree (ccbin);
+    
+    values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
+    values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum (namein (check->ccname));
+    values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum (textin (check->ccbin));
+    values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum (textin (check->ccsrc));
+    rcrel = heap_openr (RelCheckRelationName);
+    tuple = heap_formtuple (rcrel->rd_att, values, nulls);
+    CatalogOpenIndices (Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
+    heap_insert (rcrel, tuple);
+    CatalogIndexInsert (idescs, Num_pg_relcheck_indices, rcrel, tuple);
+    CatalogCloseIndices (Num_pg_relcheck_indices, idescs);
+    heap_close (rcrel);
+    
+    pfree (DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
+    pfree (DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
+    pfree (DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
+    pfree (tuple);
+
+    return;
+}
+
+static void 
+StoreConstraints (Relation rel)
+{
+    TupleConstr *constr = rel->rd_att->constr;
+    int i;
+    
+    if ( !constr )
+       return;
+    
+    if ( constr->num_defval > 0 )
+    {
+       for (i = 0; i < constr->num_defval; i++)
+           StoreAttrDefault (rel, &(constr->defval[i]));
+    }
+    
+    if ( constr->num_check > 0 )
+    {
+       for (i = 0; i < constr->num_check; i++)
+           StoreRelCheck (rel, &(constr->check[i]));
+    }
+    
+    return;
+}
+
+static void 
+RemoveAttrDefault (Relation rel)
+{
+    Relation       adrel;
+    HeapScanDesc   adscan;
+    ScanKeyData            key;
+    HeapTuple      tup;
+    
+    adrel = heap_openr (AttrDefaultRelationName);
+    
+    ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
+              ObjectIdEqualRegProcedure, rel->rd_id);
+    
+    RelationSetLockForWrite (adrel);
+    
+    adscan = heap_beginscan(adrel, 0, NowTimeQual, 1, &key);
+    
+    while (tup = heap_getnext (adscan, 0, (Buffer *)NULL), PointerIsValid(tup))
+   heap_delete (adrel, &tup->t_ctid);
+    
+    heap_endscan (adscan);
+    
+    RelationUnsetLockForWrite (adrel);
+    heap_close (adrel);
+
+}
+
+static void 
+RemoveRelCheck (Relation rel)
+{
+    Relation       rcrel;
+    HeapScanDesc   rcscan;
+    ScanKeyData            key;
+    HeapTuple      tup;
+    
+    rcrel = heap_openr (RelCheckRelationName);
+    
+    ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
+              ObjectIdEqualRegProcedure, rel->rd_id);
+    
+    RelationSetLockForWrite (rcrel);
+    
+    rcscan = heap_beginscan(rcrel, 0, NowTimeQual, 1, &key);
+    
+    while (tup = heap_getnext (rcscan, 0, (Buffer *)NULL), PointerIsValid(tup))
+   heap_delete (rcrel, &tup->t_ctid);
+    
+    heap_endscan (rcscan);
+    
+    RelationUnsetLockForWrite (rcrel);
+    heap_close (rcrel);
+
+}
 
+static void 
+RemoveConstraints (Relation rel)
+{
+    TupleConstr *constr = rel->rd_att->constr;
+    
+    if ( !constr )
+       return;
+    
+    if ( constr->num_defval > 0 )
+       RemoveAttrDefault (rel);
+    
+    if ( constr->num_check > 0 )
+       RemoveRelCheck (rel);
+    
     return;
 }
index 95b6b0e6df7c61c50f0522b97d006d1f86045ddb..b2071f814f27bc5e09ef892b75ebac8c725720b5 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.18 1997/08/21 01:32:04 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.19 1997/08/22 14:10:26 vadim Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -419,6 +419,9 @@ ConstructTupleDescriptor(Oid heapoid,
    
    ((AttributeTupleForm) to)->attnum = i+1;
    ((AttributeTupleForm) to)->attcacheoff = -1;
+   
+   ((AttributeTupleForm) to)->attnotnull = false;
+   ((AttributeTupleForm) to)->atthasdef = false;
 
    /* if the keytype is defined, we need to change the tuple form's
       atttypid & attlen field to match that of the key's type */