aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c195
-rw-r--r--src/backend/catalog/index.c5
2 files changed, 167 insertions, 33 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 5f3be132c52..7899f6c0007 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -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 <utils/builtins.h>
#include <utils/mcxt.h>
#include <utils/relcache.h>
+#include <nodes/plannodes.h>
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
#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;
}
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 95b6b0e6df7..b2071f814f2 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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 */