Fetch information about DEFAULT/CHECK while openning a relation.

This commit is contained in:
Vadim B. Mikheev 1997-08-22 03:35:44 +00:00
parent 9b6d8878fd
commit ac0029aa0b
1 changed files with 127 additions and 30 deletions

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.18 1997/08/21 04:09:51 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.19 1997/08/22 03:35:44 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@ -82,6 +82,7 @@
#include "catalog/pg_log.h"
#include "catalog/pg_time.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_relcheck.h"
#include "catalog/indexing.h"
#include "catalog/index.h"
#include "fmgr.h"
@ -260,6 +261,7 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
static void IndexedAccessMethodInitialize(Relation relation);
static void AttrDefaultFetch (Relation relation);
static void RelCheckFetch (Relation relation);
/*
* newlyCreatedRelns -
@ -482,7 +484,7 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
* RelationBuildTupleDesc
*
* Form the relation's tuple descriptor from information in
* the pg_attribute system catalog.
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
* --------------------------------
*/
static void
@ -499,13 +501,7 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
if (IsBootstrapProcessingMode())
build_tupdesc_seq(buildinfo, relation, natts);
else
{
relation->rd_att->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
relation->rd_att->constr->num_check = 0;
relation->rd_att->constr->num_defval = 0;
relation->rd_att->constr->has_not_null = false;
build_tupdesc_ind(buildinfo, relation, natts);
}
}
static void
@ -580,10 +576,13 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
Relation attrel;
HeapTuple atttup;
AttributeTupleForm attp;
TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
AttrDefault *attrdef = NULL;
int ndef = 0;
int i;
constr->has_not_null = false;
attrel = heap_openr(AttributeRelationName);
for (i = 1; i <= relation->rd_rel->relnatts; i++) {
@ -604,7 +603,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
/* Update if this attribute have a constraint */
if (attp->attnotnull)
relation->rd_att->constr->has_not_null = true;
constr->has_not_null = true;
if (attp->atthasdef)
{
@ -619,16 +618,39 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
}
heap_close(attrel);
if ( ndef > 0 )
if ( constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks )
{
if ( ndef > relation->rd_rel->relnatts )
relation->rd_att->constr->defval = (AttrDefault*)
relation->rd_att->constr = constr;
if ( ndef > 0 ) /* DEFAULTs */
{
if ( ndef < relation->rd_rel->relnatts )
constr->defval = (AttrDefault*)
repalloc (attrdef, ndef * sizeof (AttrDefault));
else
constr->defval = attrdef;
constr->num_defval = ndef;
AttrDefaultFetch (relation);
}
else
relation->rd_att->constr->defval = attrdef;
relation->rd_att->constr->num_defval = ndef;
AttrDefaultFetch (relation);
constr->num_defval = 0;
if ( relation->rd_rel->relchecks > 0 ) /* CHECKs */
{
constr->num_check = relation->rd_rel->relchecks;
constr->check = (ConstrCheck *) palloc (constr->num_check *
sizeof (ConstrCheck));
memset (constr->check, 0, constr->num_check * sizeof (ConstrCheck));
RelCheckFetch (relation);
}
else
constr->num_check = 0;
}
else
{
pfree (constr);
relation->rd_att->constr = NULL;
}
}
@ -1252,8 +1274,6 @@ static void
RelationFlushRelation(Relation *relationPtr,
bool onlyFlushReferenceCountZero)
{
int i;
AttributeTupleForm *p;
MemoryContext oldcxt;
Relation relation = *relationPtr;
@ -1268,14 +1288,8 @@ RelationFlushRelation(Relation *relationPtr,
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
RelationCacheDelete(relation);
p = relation->rd_att->attrs;
for (i = 0; i < relation->rd_rel->relnatts; i++, p++)
pfree (*p);
pfree (relation->rd_att->attrs);
if (relation->rd_att->constr)
pfree (relation->rd_att->constr);
pfree (relation->rd_att);
FreeTupleDesc (relation->rd_att);
#if 0
if (relation->rd_rules) {
@ -1641,8 +1655,9 @@ AttrDefaultFetch (Relation relation)
pfree(indexRes);
if (!HeapTupleIsValid(tuple))
continue;
found++;
adform = (Form_pg_attrdef) GETSTRUCT(tuple);
for (i = 1; i <= ndef; i++)
for (i = 0; i < ndef; i++)
{
if ( adform->adnum != attrdef[i].adnum )
continue;
@ -1667,10 +1682,10 @@ AttrDefaultFetch (Relation relation)
NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
NAMEDATALEN, relation->rd_rel->relname.data);
attrdef[i].adsrc = textout (val);
found++;
break;
}
if ( i > ndef )
if ( i >= ndef )
elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
adform->adnum,
NAMEDATALEN, relation->rd_rel->relname.data);
@ -1689,6 +1704,88 @@ AttrDefaultFetch (Relation relation)
}
static void
RelCheckFetch (Relation relation)
{
ConstrCheck *check = relation->rd_att->constr->check;
int ncheck = relation->rd_att->constr->num_check;
Relation rcrel;
Relation irel;
ScanKeyData skey;
HeapTuple tuple;
IndexScanDesc sd;
RetrieveIndexResult indexRes;
Buffer buffer;
ItemPointer iptr;
Name rcname;
struct varlena *val;
bool isnull;
int found;
ScanKeyEntryInitialize(&skey,
(bits16)0x0,
(AttrNumber)1,
(RegProcedure)ObjectIdEqualRegProcedure,
ObjectIdGetDatum(relation->rd_id));
rcrel = heap_openr(RelCheckRelationName);
irel = index_openr(RelCheckIndex);
sd = index_beginscan(irel, false, 1, &skey);
tuple = (HeapTuple)NULL;
for (found = 0; ; )
{
indexRes = index_getnext(sd, ForwardScanDirection);
if (!indexRes)
break;
iptr = &indexRes->heap_iptr;
tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
pfree(indexRes);
if (!HeapTupleIsValid(tuple))
continue;
if ( found == ncheck )
elog (WARN, "RelCheckFetch: unexpected record found for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
rcname = (Name) fastgetattr (tuple,
Anum_pg_relcheck_rcname,
rcrel->rd_att, &isnull);
if ( isnull )
elog (WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
check[found].ccname = nameout (rcname);
val = (struct varlena*) fastgetattr (tuple,
Anum_pg_relcheck_rcbin,
rcrel->rd_att, &isnull);
if ( isnull )
elog (WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
check[found].ccbin = textout (val);
val = (struct varlena*) fastgetattr (tuple,
Anum_pg_relcheck_rcsrc,
rcrel->rd_att, &isnull);
if ( isnull )
elog (WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
NAMEDATALEN, relation->rd_rel->relname.data);
check[found].ccsrc = textout (val);
found++;
ReleaseBuffer(buffer);
}
if ( found < ncheck )
elog (WARN, "RelCheckFetch: %d record not found for rel %.*s",
ncheck - found,
NAMEDATALEN, relation->rd_rel->relname.data);
index_endscan (sd);
pfree (sd);
index_close (irel);
heap_close (rcrel);
}
/*
* init_irels(), write_irels() -- handle special-case initialization of
* index relation descriptors.