diff options
author | Hiroshi Inoue <inoue@tpf.co.jp> | 2000-02-18 09:30:20 +0000 |
---|---|---|
committer | Hiroshi Inoue <inoue@tpf.co.jp> | 2000-02-18 09:30:20 +0000 |
commit | e3a97b370c2671c05ad95d6a21914c225a0cf32d (patch) | |
tree | e20b8bdc9dfedef71dfe1367c3b957cbf16c42c1 /src/backend/utils/cache | |
parent | e3befe4a66c68fea03300eadb9d9b2f1c2534dc6 (diff) | |
download | postgresql-e3a97b370c2671c05ad95d6a21914c225a0cf32d.tar.gz postgresql-e3a97b370c2671c05ad95d6a21914c225a0cf32d.zip |
Implement reindex command
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 15 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 234 | ||||
-rw-r--r-- | src/backend/utils/cache/syscache.c | 9 |
3 files changed, 179 insertions, 79 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 1f224e56cfe..c6c8763c706 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.60 2000/02/04 03:16:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.61 2000/02/18 09:28:53 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -233,7 +233,7 @@ CatalogCacheInitializeCache(struct catcache * cache, */ if (cache->cc_indname != NULL && cache->indexId == InvalidOid) { - if (RelationGetForm(relation)->relhasindex) + if (!IsIgnoringSystemIndexes() && RelationGetForm(relation)->relhasindex) { /* @@ -817,14 +817,19 @@ SearchSelfReferences(struct catcache * cache) if (!OidIsValid(indexSelfOid)) { + ScanKeyData key; + HeapScanDesc sd; /* Find oid of pg_index_indexrelid_index */ rel = heap_openr(RelationRelationName, AccessShareLock); - ntp = ClassNameIndexScan(rel, IndexRelidIndex); + ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relname, + F_NAMEEQ, PointerGetDatum(IndexRelidIndex)); + sd = heap_beginscan(rel, false, SnapshotNow, 1, &key); + ntp = heap_getnext(sd, 0); if (!HeapTupleIsValid(ntp)) elog(ERROR, "SearchSelfReferences: %s not found in %s", IndexRelidIndex, RelationRelationName); indexSelfOid = ntp->t_data->t_oid; - heap_freetuple(ntp); + heap_endscan(sd); heap_close(rel, AccessShareLock); } /* Looking for something other than pg_index_indexrelid_index? */ @@ -1031,7 +1036,7 @@ SearchSysCache(struct catcache * cache, CACHE1_elog(DEBUG, "SearchSysCache: performing scan"); if ((RelationGetForm(relation))->relhasindex - && !IsBootstrapProcessingMode()) + && !IsIgnoringSystemIndexes()) { /* ---------- * Switch back to old memory context so memory not freed diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 7c993d3d73f..16157629154 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.89 2000/01/31 04:35:52 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.90 2000/02/18 09:28:55 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -229,6 +229,7 @@ static void IndexedAccessMethodInitialize(Relation relation); static void AttrDefaultFetch(Relation relation); static void RelCheckFetch(Relation relation); +static bool criticalRelcacheBuild = false; /* ---------------------------------------------------------------- * RelationIdGetRelation() and RelationNameGetRelation() * support functions @@ -254,7 +255,7 @@ ScanPgRelation(RelationBuildDescInfo buildinfo) * can, and do. */ - if (IsBootstrapProcessingMode()) + if (IsIgnoringSystemIndexes() || !criticalRelcacheBuild) return scan_pg_rel_seq(buildinfo); else return scan_pg_rel_ind(buildinfo); @@ -424,13 +425,51 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, * can, and do. */ - if (IsBootstrapProcessingMode()) + if (IsIgnoringSystemIndexes() || !criticalRelcacheBuild) build_tupdesc_seq(buildinfo, relation, natts); else build_tupdesc_ind(buildinfo, relation, natts); } static void +SetConstrOfRelation(Relation relation, TupleConstr *constr, int ndef, AttrDefault *attrdef) +{ + if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks) + { + 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 + 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; + } +} + +static void build_tupdesc_seq(RelationBuildDescInfo buildinfo, Relation relation, u_int natts) @@ -441,7 +480,11 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, Form_pg_attribute attp; ScanKeyData key; int need; + TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr)); + AttrDefault *attrdef = NULL; + int ndef = 0; + constr->has_not_null = false; /* ---------------- * form a scan key * ---------------- @@ -478,6 +521,23 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, (char *) attp, ATTRIBUTE_TUPLE_SIZE); need--; + /* Update if this attribute have a constraint */ + if (attp->attnotnull) + constr->has_not_null = true; + + if (attp->atthasdef) + { + if (attrdef == NULL) + { + attrdef = (AttrDefault *) palloc(relation->rd_rel->relnatts * + sizeof(AttrDefault)); + MemSet(attrdef, 0, + relation->rd_rel->relnatts * sizeof(AttrDefault)); + } + attrdef[ndef].adnum = attp->attnum; + attrdef[ndef].adbin = NULL; + ndef++; + } } pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0); } @@ -492,6 +552,8 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, */ heap_endscan(pg_attribute_scan); heap_close(pg_attribute_desc, AccessShareLock); + + SetConstrOfRelation(relation, constr, ndef, attrdef); } static void @@ -549,39 +611,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, heap_close(attrel, AccessShareLock); - if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks) - { - 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 - 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; - } + SetConstrOfRelation(relation, constr, ndef, attrdef); } @@ -1806,16 +1836,19 @@ AttrDefaultFetch(Relation relation) AttrDefault *attrdef = relation->rd_att->constr->defval; int ndef = relation->rd_att->constr->num_defval; Relation adrel; - Relation irel; + Relation irel = (Relation) NULL; ScanKeyData skey; HeapTupleData tuple; + HeapTuple htup; Form_pg_attrdef adform; - IndexScanDesc sd; + IndexScanDesc sd = (IndexScanDesc) NULL; + HeapScanDesc adscan = (HeapScanDesc) NULL; RetrieveIndexResult indexRes; struct varlena *val; bool isnull; int found; int i; + bool hasindex; ScanKeyEntryInitialize(&skey, (bits16) 0x0, @@ -1824,8 +1857,14 @@ AttrDefaultFetch(Relation relation) ObjectIdGetDatum(RelationGetRelid(relation))); adrel = heap_openr(AttrDefaultRelationName, AccessShareLock); - irel = index_openr(AttrDefaultIndex); - sd = index_beginscan(irel, false, 1, &skey); + hasindex = (adrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes()); + if (hasindex) + { + irel = index_openr(AttrDefaultIndex); + sd = index_beginscan(irel, false, 1, &skey); + } + else + adscan = heap_beginscan(adrel, false, SnapshotNow, 1, &skey); tuple.t_datamcxt = NULL; tuple.t_data = NULL; @@ -1833,17 +1872,27 @@ AttrDefaultFetch(Relation relation) { Buffer buffer; - indexRes = index_getnext(sd, ForwardScanDirection); - if (!indexRes) - break; - - tuple.t_self = indexRes->heap_iptr; - heap_fetch(adrel, SnapshotNow, &tuple, &buffer); - pfree(indexRes); - if (tuple.t_data == NULL) - continue; + if (hasindex) + { + indexRes = index_getnext(sd, ForwardScanDirection); + if (!indexRes) + break; + + tuple.t_self = indexRes->heap_iptr; + heap_fetch(adrel, SnapshotNow, &tuple, &buffer); + pfree(indexRes); + if (tuple.t_data == NULL) + continue; + htup = &tuple; + } + else + { + htup = heap_getnext(adscan, 0); + if (!HeapTupleIsValid(htup)) + break; + } found++; - adform = (Form_pg_attrdef) GETSTRUCT(&tuple); + adform = (Form_pg_attrdef) GETSTRUCT(htup); for (i = 0; i < ndef; i++) { if (adform->adnum != attrdef[i].adnum) @@ -1853,7 +1902,7 @@ AttrDefaultFetch(Relation relation) NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname), RelationGetRelationName(relation)); - val = (struct varlena *) fastgetattr(&tuple, + val = (struct varlena *) fastgetattr(htup, Anum_pg_attrdef_adbin, adrel->rd_att, &isnull); if (isnull) @@ -1863,7 +1912,8 @@ AttrDefaultFetch(Relation relation) attrdef[i].adbin = textout(val); break; } - ReleaseBuffer(buffer); + if (hasindex) + ReleaseBuffer(buffer); if (i >= ndef) elog(NOTICE, "AttrDefaultFetch: unexpected record found for attr %d in rel %s", @@ -1875,8 +1925,13 @@ AttrDefaultFetch(Relation relation) elog(NOTICE, "AttrDefaultFetch: %d record not found for rel %s", ndef - found, RelationGetRelationName(relation)); - index_endscan(sd); - index_close(irel); + if (hasindex) + { + index_endscan(sd); + index_close(irel); + } + else + heap_endscan(adscan); heap_close(adrel, AccessShareLock); } @@ -1886,15 +1941,18 @@ RelCheckFetch(Relation relation) ConstrCheck *check = relation->rd_att->constr->check; int ncheck = relation->rd_att->constr->num_check; Relation rcrel; - Relation irel; + Relation irel = (Relation)NULL; ScanKeyData skey; HeapTupleData tuple; - IndexScanDesc sd; + HeapTuple htup; + IndexScanDesc sd = (IndexScanDesc)NULL; + HeapScanDesc rcscan = (HeapScanDesc)NULL; RetrieveIndexResult indexRes; Name rcname; struct varlena *val; bool isnull; int found; + bool hasindex; ScanKeyEntryInitialize(&skey, (bits16) 0x0, @@ -1903,8 +1961,14 @@ RelCheckFetch(Relation relation) ObjectIdGetDatum(RelationGetRelid(relation))); rcrel = heap_openr(RelCheckRelationName, AccessShareLock); - irel = index_openr(RelCheckIndex); - sd = index_beginscan(irel, false, 1, &skey); + hasindex = (rcrel->rd_rel->relhasindex && !IsIgnoringSystemIndexes()); + if (hasindex) + { + irel = index_openr(RelCheckIndex); + sd = index_beginscan(irel, false, 1, &skey); + } + else + rcscan = heap_beginscan(rcrel, false, SnapshotNow, 1, &skey); tuple.t_datamcxt = NULL; tuple.t_data = NULL; @@ -1912,27 +1976,37 @@ RelCheckFetch(Relation relation) { Buffer buffer; - indexRes = index_getnext(sd, ForwardScanDirection); - if (!indexRes) - break; - - tuple.t_self = indexRes->heap_iptr; - heap_fetch(rcrel, SnapshotNow, &tuple, &buffer); - pfree(indexRes); - if (tuple.t_data == NULL) - continue; + if (hasindex) + { + indexRes = index_getnext(sd, ForwardScanDirection); + if (!indexRes) + break; + + tuple.t_self = indexRes->heap_iptr; + heap_fetch(rcrel, SnapshotNow, &tuple, &buffer); + pfree(indexRes); + if (tuple.t_data == NULL) + continue; + htup = &tuple; + } + else + { + htup = heap_getnext(rcscan, 0); + if (!HeapTupleIsValid(htup)) + break; + } if (found == ncheck) elog(ERROR, "RelCheckFetch: unexpected record found for rel %s", RelationGetRelationName(relation)); - rcname = (Name) fastgetattr(&tuple, + rcname = (Name) fastgetattr(htup, Anum_pg_relcheck_rcname, rcrel->rd_att, &isnull); if (isnull) elog(ERROR, "RelCheckFetch: rcname IS NULL for rel %s", RelationGetRelationName(relation)); check[found].ccname = pstrdup(NameStr(*rcname)); - val = (struct varlena *) fastgetattr(&tuple, + val = (struct varlena *) fastgetattr(htup, Anum_pg_relcheck_rcbin, rcrel->rd_att, &isnull); if (isnull) @@ -1940,15 +2014,21 @@ RelCheckFetch(Relation relation) RelationGetRelationName(relation)); check[found].ccbin = textout(val); found++; - ReleaseBuffer(buffer); + if (hasindex) + ReleaseBuffer(buffer); } if (found < ncheck) elog(ERROR, "RelCheckFetch: %d record not found for rel %s", ncheck - found, RelationGetRelationName(relation)); - index_endscan(sd); - index_close(irel); + if (hasindex) + { + index_endscan(sd); + index_close(irel); + } + else + heap_endscan(rcscan); heap_close(rcrel, AccessShareLock); } @@ -2148,6 +2228,7 @@ init_irels(void) RelationCacheInsert(ird); } + criticalRelcacheBuild = true; } static void @@ -2162,7 +2243,6 @@ write_irels(void) Form_pg_class relform; IndexStrategy strat; RegProcedure *support; - ProcessingMode oldmode; int i; int relno; RelationBuildDescInfo bi; @@ -2186,8 +2266,13 @@ write_irels(void) * descriptors, nail them into cache so we never lose them. */ + /* Removed the following ProcessingMode change -- inoue + * At this point + * 1) Catalog Cache isn't initialized + * 2) Relation Cache for the following critical indexes aren't built oldmode = GetProcessingMode(); SetProcessingMode(BootstrapProcessing); + */ bi.infotype = INFO_RELNAME; bi.i.info_name = AttributeRelidNumIndex; @@ -2202,7 +2287,10 @@ write_irels(void) irel[2] = RelationBuildDesc(bi, NULL); irel[2]->rd_isnailed = true; + criticalRelcacheBuild = true; + /* Removed the following ProcessingMode -- inoue SetProcessingMode(oldmode); + */ /* * Write out the index reldescs to the special cache file. diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 3cc75198994..087002ab76f 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.48 2000/01/26 05:57:18 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.49 2000/02/18 09:28:56 inoue Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -39,6 +39,7 @@ #include "catalog/pg_type.h" #include "utils/catcache.h" #include "utils/temprel.h" +#include "miscadmin.h" extern bool AMI_OVERRIDE; /* XXX style */ @@ -395,6 +396,11 @@ static struct cachedesc cacheinfo[] = { static struct catcache *SysCache[lengthof(cacheinfo)]; static int32 SysCacheSize = lengthof(cacheinfo); +static bool CacheInitialized = false; +extern bool IsCacheInitialized(void) +{ + return CacheInitialized; +} /* @@ -442,6 +448,7 @@ InitCatalogCache() } } + CacheInitialized = true; } /* |