From 197ced5923164ab1ea6ca958d084d2e4ba46fd14 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" <vadim4o@yahoo.com> Date: Thu, 21 Aug 1997 01:36:09 +0000 Subject: [PATCH] Read info for DEFAULT from pg_attrdef. --- src/backend/utils/cache/relcache.c | 195 +++++++++++++++++++++++------ 1 file changed, 154 insertions(+), 41 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 69e34d3aa4..8cb08e6ab1 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.16 1997/08/20 14:54:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.17 1997/08/21 01:36:09 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -81,6 +81,7 @@ #include "catalog/pg_variable.h" #include "catalog/pg_log.h" #include "catalog/pg_time.h" +#include "catalog/pg_attrdef.h" #include "catalog/indexing.h" #include "catalog/index.h" #include "fmgr.h" @@ -90,22 +91,6 @@ static void RelationFlushRelation(Relation *relationPtr, static Relation RelationNameCacheGetRelation(char *relationName); static void init_irels(void); static void write_irels(void); -/* non-export function prototypes */ -static void formrdesc(char *relationName, u_int natts, - FormData_pg_attribute att[]); -static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo); -static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo); -static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo); -static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp); -static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, - Relation relation, AttributeTupleForm attp, u_int natts); -static void build_tupdesc_seq(RelationBuildDescInfo buildinfo, - Relation relation, AttributeTupleForm attp, u_int natts); -static void build_tupdesc_ind(RelationBuildDescInfo buildinfo, - Relation relation, AttributeTupleForm attp, u_int natts); -static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo); -static void IndexedAccessMethodInitialize(Relation relation); - /* ---------------- * defines @@ -254,6 +239,28 @@ typedef struct relnamecacheent { } \ } +/* non-export function prototypes */ +static void formrdesc(char *relationName, u_int natts, + FormData_pg_attribute att[]); + +#if 0 /* See comments at line 1304 */ +static void RelationFlushIndexes(Relation *r, Oid accessMethodId); +#endif + +static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo); +static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo); +static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo); +static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp); +static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, + Relation relation, u_int natts); +static void build_tupdesc_seq(RelationBuildDescInfo buildinfo, + Relation relation, u_int natts); +static void build_tupdesc_ind(RelationBuildDescInfo buildinfo, + Relation relation, u_int natts); +static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo); +static void IndexedAccessMethodInitialize(Relation relation); +static void AttrDefaultFetch (Relation relation); + /* * newlyCreatedRelns - * relations created during this transaction. We need to keep track of @@ -268,7 +275,7 @@ static List *newlyCreatedRelns = NULL; */ -#ifdef NOT_USED /* XXX This doesn't seem to be used anywhere */ +#if NOT_USED /* XXX This doesn't seem to be used anywhere */ /* -------------------------------- * BuildDescInfoError returns a string appropriate to * the buildinfo passed to it @@ -481,7 +488,6 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp) static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, Relation relation, - AttributeTupleForm attp, u_int natts) { /* @@ -491,20 +497,26 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, */ if (IsBootstrapProcessingMode()) - build_tupdesc_seq(buildinfo, relation, attp, natts); + build_tupdesc_seq(buildinfo, relation, natts); else - build_tupdesc_ind(buildinfo, relation, attp, natts); + { + relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); + 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 build_tupdesc_seq(RelationBuildDescInfo buildinfo, Relation relation, - AttributeTupleForm attp, u_int natts) { HeapTuple pg_attribute_tuple; Relation pg_attribute_desc; HeapScanDesc pg_attribute_scan; + AttributeTupleForm attp; ScanKeyData key; int need; @@ -530,9 +542,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, * ---------------- */ need = natts; - if (!relation->rd_att->constr) - relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); - relation->rd_att->constr->has_not_null = false; pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL); while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) { @@ -545,11 +554,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]), (char *) attp, ATTRIBUTE_TUPLE_SIZE); - - /* Update if this attribute have a constraint */ - if (attp->attnotnull) - relation->rd_att->constr->has_not_null = true; - need--; } pg_attribute_tuple = heap_getnext(pg_attribute_scan, @@ -571,17 +575,15 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, static void build_tupdesc_ind(RelationBuildDescInfo buildinfo, Relation relation, - AttributeTupleForm attp, u_int natts) { Relation attrel; HeapTuple atttup; + AttributeTupleForm attp; + AttrDefault *attrdef = NULL; + int ndef = 0; int i; - if (!relation->rd_att->constr) - relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); - relation->rd_att->constr->has_not_null = false; - attrel = heap_openr(AttributeRelationName); for (i = 1; i <= relation->rd_rel->relnatts; i++) { @@ -589,8 +591,8 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i); if (!HeapTupleIsValid(atttup)) - elog(WARN, "cannot find attribute %d of relation %.16s", i, - &(relation->rd_rel->relname.data[0])); + elog(WARN, "cannot find attribute %d of relation %.*s", i, + NAMEDATALEN, &(relation->rd_rel->relname.data[0])); attp = (AttributeTupleForm) GETSTRUCT(atttup); relation->rd_att->attrs[i - 1] = @@ -602,10 +604,33 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, /* Update if this attribute have a constraint */ if (attp->attnotnull) - relation->rd_att->constr->has_not_null = true; + relation->rd_att->constr->has_not_null = true; + + if (attp->atthasdef) + { + if ( attrdef == NULL ) + attrdef = (AttrDefault*) palloc (relation->rd_rel->relnatts * + sizeof (AttrDefault)); + attrdef[ndef].adnum = i; + attrdef[ndef].adbin = NULL; + attrdef[ndef].adsrc = NULL; + ndef++; + } } heap_close(attrel); + + if ( ndef > 0 ) + { + if ( ndef > relation->rd_rel->relnatts ) + relation->rd_att->constr->defval = (AttrDefault*) + repalloc (attrdef, ndef * sizeof (AttrDefault)); + else + relation->rd_att->constr->defval = attrdef; + relation->rd_att->constr->num_defval = ndef; + AttrDefaultFetch (relation); + } + } /* -------------------------------- @@ -759,7 +784,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo) Oid relid; Oid relam; Form_pg_class relp; - AttributeTupleForm attp = NULL; MemoryContext oldcxt; @@ -834,7 +858,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo) * already allocated for it by AllocateRelationDesc. * ---------------- */ - RelationBuildTupleDesc(buildinfo, relation, attp, natts); + RelationBuildTupleDesc(buildinfo, relation, natts); /* ---------------- * initialize rules that affect this relation @@ -1346,7 +1370,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId) } } -#ifdef NOT_USED /* See comments at line 1304 */ +#if NOT_USED /* See comments at line 1304 */ /* -------------------------------- * RelationIdInvalidateRelationCacheByAccessMethodId * @@ -1576,6 +1600,95 @@ RelationInitialize(void) MemoryContextSwitchTo(oldcxt); } +static void +AttrDefaultFetch (Relation relation) +{ + AttrDefault *attrdef = relation->rd_att->constr->defval; + int ndef = relation->rd_att->constr->num_defval; + Relation adrel; + Relation irel; + ScanKeyData skey; + HeapTuple tuple; + Form_pg_attrdef adform; + IndexScanDesc sd; + RetrieveIndexResult indexRes; + Buffer buffer; + ItemPointer iptr; + struct varlena *val; + bool isnull; + int found; + int i; + + ScanKeyEntryInitialize(&skey, + (bits16)0x0, + (AttrNumber)1, + (RegProcedure)ObjectIdEqualRegProcedure, + ObjectIdGetDatum(relation->rd_id)); + + adrel = heap_openr(AttrDefaultRelationName); + irel = index_openr(AttrDefaultIndex); + 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(adrel, NowTimeQual, iptr, &buffer); + pfree(indexRes); + if (!HeapTupleIsValid(tuple)) + continue; + adform = (Form_pg_attrdef) GETSTRUCT(tuple); + for (i = 1; i <= ndef; i++) + { + if ( adform->adnum != attrdef[i].adnum ) + continue; + if ( attrdef[i].adsrc != NULL ) + elog (WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s", + NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data, + NAMEDATALEN, relation->rd_rel->relname.data); + + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_attrdef_adbin, + adrel->rd_att, &isnull); + if ( isnull ) + elog (WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s", + NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data, + NAMEDATALEN, relation->rd_rel->relname.data); + attrdef[i].adbin = textout (val); + val = (struct varlena*) fastgetattr (tuple, + Anum_pg_attrdef_adsrc, + adrel->rd_att, &isnull); + if ( isnull ) + elog (WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s", + NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data, + NAMEDATALEN, relation->rd_rel->relname.data); + attrdef[i].adsrc = textout (val); + found++; + } + + if ( i > ndef ) + elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s", + adform->adnum, + NAMEDATALEN, relation->rd_rel->relname.data); + ReleaseBuffer(buffer); + } + + if ( found < ndef ) + elog (WARN, "AttrDefaultFetch: %d record not found for rel %.*s", + ndef - found, + NAMEDATALEN, relation->rd_rel->relname.data); + + index_endscan (sd); + pfree (sd); + index_close (irel); + heap_close (adrel); + +} + /* * init_irels(), write_irels() -- handle special-case initialization of * index relation descriptors. -- 2.40.0