From 314043749573f8638bd779298860828c44484ca4 Mon Sep 17 00:00:00 2001 From: Neil Conway Date: Wed, 11 May 2005 06:24:55 +0000 Subject: [PATCH] This patch refactors away some duplicated code in the index AM build methods: they all invoke UpdateStats() since they have computed the number of heap tuples, so I created a function in catalog/index.c that each AM now calls. --- src/backend/access/gist/gist.c | 25 +++------------------ src/backend/access/hash/hash.c | 25 +++------------------ src/backend/access/nbtree/nbtree.c | 25 +++------------------ src/backend/access/rtree/rtree.c | 25 +++------------------ src/backend/catalog/index.c | 35 ++++++++++++++++++++++++++++-- src/include/catalog/index.h | 5 +++-- 6 files changed, 48 insertions(+), 92 deletions(-) diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index c1e3dfae36..e02f0a3762 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.113 2005/03/21 01:23:56 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.114 2005/05/11 06:24:50 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -184,27 +184,8 @@ gistbuild(PG_FUNCTION_ARGS) /* okay, all heap tuples are indexed */ - /* - * Since we just counted the tuples in the heap, we update its stats - * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during normal - * index definitions, not for indices on system catalogs created - * during bootstrap processing. We must close the relations before - * updating statistics to guarantee that the relcache entries are - * flushed when we increment the command counter in UpdateStats(). But - * we do not release any locks on the relations; those will be held - * until end of transaction. - */ - if (IsNormalProcessingMode()) - { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); - - heap_close(heap, NoLock); - index_close(index); - UpdateStats(hrelid, reltuples); - UpdateStats(irelid, buildstate.indtuples); - } + /* since we just counted the # of tuples, may as well update stats */ + IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples); freeGISTstate(&buildstate.giststate); #ifdef GISTDEBUG diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 7b15937766..6eda509114 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.78 2005/03/27 23:52:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.79 2005/05/11 06:24:51 neilc Exp $ * * NOTES * This file contains only the public interface routines. @@ -72,27 +72,8 @@ hashbuild(PG_FUNCTION_ARGS) reltuples = IndexBuildHeapScan(heap, index, indexInfo, hashbuildCallback, (void *) &buildstate); - /* - * Since we just counted the tuples in the heap, we update its stats - * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during normal - * index definitions, not for indices on system catalogs created - * during bootstrap processing. We must close the relations before - * updating statistics to guarantee that the relcache entries are - * flushed when we increment the command counter in UpdateStats(). But - * we do not release any locks on the relations; those will be held - * until end of transaction. - */ - if (IsNormalProcessingMode()) - { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); - - heap_close(heap, NoLock); - index_close(index); - UpdateStats(hrelid, reltuples); - UpdateStats(irelid, buildstate.indtuples); - } + /* since we just counted the # of tuples, may as well update stats */ + IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples); PG_RETURN_VOID(); } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index b57ab37a5b..84ce90c5ca 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -12,7 +12,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.129 2005/05/07 21:32:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.130 2005/05/11 06:24:53 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -148,27 +148,8 @@ btbuild(PG_FUNCTION_ARGS) } #endif /* BTREE_BUILD_STATS */ - /* - * Since we just counted the tuples in the heap, we update its stats - * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during normal - * index definitions, not for indices on system catalogs created - * during bootstrap processing. We must close the relations before - * updating statistics to guarantee that the relcache entries are - * flushed when we increment the command counter in UpdateStats(). But - * we do not release any locks on the relations; those will be held - * until end of transaction. - */ - if (IsNormalProcessingMode()) - { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); - - heap_close(heap, NoLock); - index_close(index); - UpdateStats(hrelid, reltuples); - UpdateStats(irelid, buildstate.indtuples); - } + /* since we just counted the # of tuples, may as well update stats */ + IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples); PG_RETURN_VOID(); } diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c index 32f4ebaf80..ce8fb655b6 100644 --- a/src/backend/access/rtree/rtree.c +++ b/src/backend/access/rtree/rtree.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/rtree/rtree.c,v 1.88 2005/03/21 01:24:00 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/rtree/rtree.c,v 1.89 2005/05/11 06:24:54 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -142,27 +142,8 @@ rtbuild(PG_FUNCTION_ARGS) /* okay, all heap tuples are indexed */ - /* - * Since we just counted the tuples in the heap, we update its stats - * in pg_class to guarantee that the planner takes advantage of the - * index we just created. But, only update statistics during normal - * index definitions, not for indices on system catalogs created - * during bootstrap processing. We must close the relations before - * updating statistics to guarantee that the relcache entries are - * flushed when we increment the command counter in UpdateStats(). But - * we do not release any locks on the relations; those will be held - * until end of transaction. - */ - if (IsNormalProcessingMode()) - { - Oid hrelid = RelationGetRelid(heap); - Oid irelid = RelationGetRelid(index); - - heap_close(heap, NoLock); - index_close(index); - UpdateStats(hrelid, reltuples); - UpdateStats(irelid, buildstate.indtuples); - } + /* since we just counted the # of tuples, may as well update stats */ + IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples); PG_RETURN_VOID(); } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index ae02a890d4..9ad6b343a3 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.254 2005/05/06 17:24:52 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.255 2005/05/11 06:24:54 neilc Exp $ * * * INTERFACE ROUTINES @@ -62,6 +62,7 @@ static void UpdateIndexRelation(Oid indexoid, Oid heapoid, Oid *classOids, bool primary); static Oid IndexGetRelation(Oid indexId); +static void UpdateStats(Oid relid, double reltuples); /* @@ -1149,6 +1150,36 @@ setNewRelfilenode(Relation relation) } +/* + * This is invoked by the various index AMs once they have finished + * constructing an index. Constructing an index involves counting the + * number of tuples in both the relation and the index, so we take + * advantage of the opportunity to update pg_class to ensure that the + * planner takes advantage of the index we just created. But, only + * update statistics during normal index definitions, not for indices + * on system catalogs created during bootstrap processing. We must + * close the relations before updating statistics to guarantee that + * the relcache entries are flushed when we increment the command + * counter in UpdateStats(). But we do not release any locks on the + * relations; those will be held until end of transaction. + */ +void +IndexCloseAndUpdateStats(Relation heap, double heapTuples, + Relation index, double indexTuples) +{ + Oid hrelid = RelationGetRelid(heap); + Oid irelid = RelationGetRelid(index); + + if (!IsNormalProcessingMode()) + return; + + heap_close(heap, NoLock); + index_close(index); + UpdateStats(hrelid, heapTuples); + UpdateStats(irelid, indexTuples); +} + + /* ---------------- * UpdateStats * @@ -1157,7 +1188,7 @@ setNewRelfilenode(Relation relation) * in the context of VACUUM, only CREATE INDEX. * ---------------- */ -void +static void UpdateStats(Oid relid, double reltuples) { Relation whichRel; diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index f8bfdfb526..8076f84a46 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.62 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.63 2005/05/11 06:24:55 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -52,7 +52,8 @@ extern void FormIndexDatum(IndexInfo *indexInfo, Datum *values, bool *isnull); -extern void UpdateStats(Oid relid, double reltuples); +extern void IndexCloseAndUpdateStats(Relation heap, double heapTuples, + Relation index, double indexTuples); extern void setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid);