From ac0029aa0b739b6508509f68f833c462cfb73f5e Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Fri, 22 Aug 1997 03:35:44 +0000 Subject: [PATCH] Fetch information about DEFAULT/CHECK while openning a relation. --- src/backend/utils/cache/relcache.c | 157 +++++++++++++++++++++++------ 1 file changed, 127 insertions(+), 30 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fa52573b2d..258e764ecf 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -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. -- 2.40.0