mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Remove DEFAULT/CHECK infos from catalog on DROP TABLE
Store CHECK infos on CREATE TABLE
This commit is contained in:
parent
021778eed3
commit
530876fea5
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
* heap_creatr() - Create an uncataloged heap relation
|
* heap_creatr() - Create an uncataloged heap relation
|
||||||
@ -50,6 +50,7 @@
|
|||||||
#include <utils/builtins.h>
|
#include <utils/builtins.h>
|
||||||
#include <utils/mcxt.h>
|
#include <utils/mcxt.h>
|
||||||
#include <utils/relcache.h>
|
#include <utils/relcache.h>
|
||||||
|
#include <nodes/plannodes.h>
|
||||||
#ifndef HAVE_MEMMOVE
|
#ifndef HAVE_MEMMOVE
|
||||||
# include <regex/utils.h>
|
# include <regex/utils.h>
|
||||||
#else
|
#else
|
||||||
@ -68,8 +69,7 @@ static void RelationRemoveInheritance(Relation relation);
|
|||||||
static void RemoveFromTempRelList(Relation r);
|
static void RemoveFromTempRelList(Relation r);
|
||||||
static void addNewRelationType(char *typeName, Oid new_rel_oid);
|
static void addNewRelationType(char *typeName, Oid new_rel_oid);
|
||||||
static void StoreConstraints (Relation rel);
|
static void StoreConstraints (Relation rel);
|
||||||
static void StoreAttrDefault (Relation rel, AttrDefault *attrdef);
|
static void RemoveConstraints (Relation rel);
|
||||||
static void StoreRelCheck (Relation rel, ConstrCheck *check);
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
@ -371,8 +371,10 @@ heap_creatr(char *name,
|
|||||||
*
|
*
|
||||||
* 6) AddPgRelationTuple() is called to register the
|
* 6) AddPgRelationTuple() is called to register the
|
||||||
* relation itself in the catalogs.
|
* 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.
|
* is returned.
|
||||||
*
|
*
|
||||||
* old comments:
|
* old comments:
|
||||||
@ -847,7 +849,8 @@ heap_create(char relname[],
|
|||||||
* 4) remove pg_class tuple
|
* 4) remove pg_class tuple
|
||||||
* 5) remove pg_attribute tuples
|
* 5) remove pg_attribute tuples
|
||||||
* 6) remove pg_type tuples
|
* 6) remove pg_type tuples
|
||||||
* 7) unlink relation
|
* 7) RemoveConstraints ()
|
||||||
|
* 8) unlink relation
|
||||||
*
|
*
|
||||||
* old comments
|
* old comments
|
||||||
* Except for vital relations, removes relation from
|
* Except for vital relations, removes relation from
|
||||||
@ -1327,6 +1330,8 @@ heap_destroy(char *relname)
|
|||||||
* Does nothing!!! Flushing moved below. - vadim 06/04/97
|
* Does nothing!!! Flushing moved below. - vadim 06/04/97
|
||||||
RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
|
RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
RemoveConstraints (rdesc);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* unlink the relation and finish up.
|
* unlink the relation and finish up.
|
||||||
@ -1468,30 +1473,6 @@ DestroyTempRels(void)
|
|||||||
tempRels = NULL;
|
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 *flatten_tlist(List *tlist);
|
||||||
extern List *pg_plan(char *query_string, Oid *typev, int nargs,
|
extern List *pg_plan(char *query_string, Oid *typev, int nargs,
|
||||||
QueryTreeList **queryListP, CommandDest dest);
|
QueryTreeList **queryListP, CommandDest dest);
|
||||||
@ -1520,12 +1501,14 @@ StoreAttrDefault (Relation rel, AttrDefault *attrdef)
|
|||||||
start:;
|
start:;
|
||||||
sprintf (str, "select %s%s from %.*s", attrdef->adsrc, cast,
|
sprintf (str, "select %s%s from %.*s", attrdef->adsrc, cast,
|
||||||
NAMEDATALEN, rel->rd_rel->relname.data);
|
NAMEDATALEN, rel->rd_rel->relname.data);
|
||||||
|
setheapoverride(true);
|
||||||
planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
|
planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
|
||||||
|
setheapoverride(false);
|
||||||
query = (Query*) (queryTree_list->qtrees[0]);
|
query = (Query*) (queryTree_list->qtrees[0]);
|
||||||
|
|
||||||
if ( length (query->rtable) > 1 ||
|
if ( length (query->rtable) > 1 ||
|
||||||
flatten_tlist (query->targetList) != NIL )
|
flatten_tlist (query->targetList) != NIL )
|
||||||
elog (WARN, "AttributeDefault: cannot use attribute(s)");
|
elog (WARN, "DEFAULT: cannot use attribute(s)");
|
||||||
te = (TargetEntry *) lfirst (query->targetList);
|
te = (TargetEntry *) lfirst (query->targetList);
|
||||||
resdom = te->resdom;
|
resdom = te->resdom;
|
||||||
expr = te->expr;
|
expr = te->expr;
|
||||||
@ -1535,13 +1518,13 @@ start:;
|
|||||||
if ( ((Const*)expr)->consttype != atp->atttypid )
|
if ( ((Const*)expr)->consttype != atp->atttypid )
|
||||||
{
|
{
|
||||||
if ( *cast != 0 )
|
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));
|
sprintf (cast, ":: %s", get_id_typname (atp->atttypid));
|
||||||
goto start;
|
goto start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( exprType (expr) != atp->atttypid )
|
else if ( exprType (expr) != atp->atttypid )
|
||||||
elog (WARN, "AttributeDefault: type mismatched");
|
elog (WARN, "DEFAULT: type mismatched");
|
||||||
|
|
||||||
adbin = nodeToString (expr);
|
adbin = nodeToString (expr);
|
||||||
oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
|
oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
|
||||||
@ -1560,6 +1543,7 @@ start:;
|
|||||||
heap_insert (adrel, tuple);
|
heap_insert (adrel, tuple);
|
||||||
CatalogIndexInsert (idescs, Num_pg_attrdef_indices, adrel, tuple);
|
CatalogIndexInsert (idescs, Num_pg_attrdef_indices, adrel, tuple);
|
||||||
CatalogCloseIndices (Num_pg_attrdef_indices, idescs);
|
CatalogCloseIndices (Num_pg_attrdef_indices, idescs);
|
||||||
|
heap_close (adrel);
|
||||||
|
|
||||||
pfree (DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
|
pfree (DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
|
||||||
pfree (DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
|
pfree (DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
|
||||||
@ -1570,6 +1554,153 @@ start:;
|
|||||||
static void
|
static void
|
||||||
StoreRelCheck (Relation rel, ConstrCheck *check)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
@ -419,6 +419,9 @@ ConstructTupleDescriptor(Oid heapoid,
|
|||||||
|
|
||||||
((AttributeTupleForm) to)->attnum = i+1;
|
((AttributeTupleForm) to)->attnum = i+1;
|
||||||
((AttributeTupleForm) to)->attcacheoff = -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
|
/* if the keytype is defined, we need to change the tuple form's
|
||||||
atttypid & attlen field to match that of the key's type */
|
atttypid & attlen field to match that of the key's type */
|
||||||
|
Loading…
Reference in New Issue
Block a user