1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Add FILLFACTOR to CREATE INDEX.

ITAGAKI Takahiro
This commit is contained in:
Bruce Momjian
2006-07-02 02:23:23 +00:00
parent 5d5c1416bf
commit 277807bd9e
65 changed files with 1458 additions and 309 deletions

View File

@@ -16,7 +16,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.107 2006/06/27 02:51:39 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.108 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1738,3 +1738,54 @@ heap_addheader(int natts, /* max domain index */
return tuple;
}
/*
* build_class_tuple
*
* XXX Natts_pg_class_fixed is a hack - see pg_class.h
*/
HeapTuple
build_class_tuple(Form_pg_class pgclass, ArrayType *options)
{
HeapTuple tuple;
HeapTupleHeader td;
Form_pg_class data; /* contents of tuple */
Size len;
Size size;
int hoff;
/* size of pg_class tuple with options */
if (options)
size = offsetof(FormData_pg_class, reloptions) + VARATT_SIZE(options);
else
size = CLASS_TUPLE_SIZE;
/* header needs no null bitmap */
hoff = offsetof(HeapTupleHeaderData, t_bits);
hoff += sizeof(Oid);
hoff = MAXALIGN(hoff);
len = hoff + size;
tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
tuple->t_len = len;
ItemPointerSetInvalid(&(tuple->t_self));
tuple->t_tableOid = InvalidOid;
/* we don't bother to fill the Datum fields */
td->t_natts = Natts_pg_class_fixed;
td->t_hoff = hoff;
td->t_infomask = HEAP_HASOID;
data = (Form_pg_class) ((char *) td + hoff);
memcpy(data, pgclass, CLASS_TUPLE_SIZE);
if (options)
{
td->t_natts++;
memcpy(data->reloptions, options, VARATT_SIZE(options));
}
return tuple;
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.1 2006/05/02 11:28:54 teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.2 2006/07/02 02:23:18 momjian Exp $
*-------------------------------------------------------------------------
*/
@@ -201,3 +201,17 @@ GinPageGetCopyPage( Page page ) {
return tmppage;
}
Datum
ginoption(PG_FUNCTION_ARGS)
{
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
if (options != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("GIN does not support parameters at all")));
/* Do not use PG_RETURN_NULL. */
PG_RETURN_BYTEA_P(NULL);
}

View File

@@ -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.139 2006/06/28 12:00:14 teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.140 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,6 +44,7 @@ static void gistbuildCallback(Relation index,
void *state);
static void gistdoinsert(Relation r,
IndexTuple itup,
Size freespace,
GISTSTATE *GISTstate);
static void gistfindleaf(GISTInsertState *state,
GISTSTATE *giststate);
@@ -197,7 +198,8 @@ gistbuildCallback(Relation index,
* you're inserting single tups, but not when you're initializing the
* whole index at once.
*/
gistdoinsert(index, itup, &buildstate->giststate);
gistdoinsert(index, itup, IndexGetPageFreeSpace(index),
&buildstate->giststate);
buildstate->indtuples += 1;
MemoryContextSwitchTo(oldCtx);
@@ -236,7 +238,7 @@ gistinsert(PG_FUNCTION_ARGS)
values, isnull, true /* size is currently bogus */);
itup->t_tid = *ht_ctid;
gistdoinsert(r, itup, &giststate);
gistdoinsert(r, itup, 0, &giststate);
/* cleanup */
freeGISTstate(&giststate);
@@ -253,7 +255,7 @@ gistinsert(PG_FUNCTION_ARGS)
* so it does not bother releasing palloc'd allocations.
*/
static void
gistdoinsert(Relation r, IndexTuple itup, GISTSTATE *giststate)
gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
{
GISTInsertState state;
@@ -263,6 +265,7 @@ gistdoinsert(Relation r, IndexTuple itup, GISTSTATE *giststate)
state.itup[0] = (IndexTuple) palloc(IndexTupleSize(itup));
memcpy(state.itup[0], itup, IndexTupleSize(itup));
state.ituplen = 1;
state.freespace = freespace;
state.r = r;
state.key = itup->t_tid;
state.needInsertComplete = true;
@@ -294,7 +297,11 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
*/
if (gistnospace(state->stack->page, state->itup, state->ituplen, (is_leaf) ? InvalidOffsetNumber : state->stack->childoffnum))
/*
* XXX: If we want to change fillfactors between node and leaf,
* fillfactor = (is_leaf ? state->leaf_fillfactor : state->node_fillfactor)
*/
if (gistnospace(state->stack->page, state->itup, state->ituplen, (is_leaf) ? InvalidOffsetNumber : state->stack->childoffnum, state->freespace))
{
/* no space for insertion */
IndexTuple *itvec;

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.16 2006/06/28 12:00:14 teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.17 2006/07/02 02:23:18 momjian Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -58,9 +58,9 @@ gistfillbuffer(Relation r, Page page, IndexTuple *itup,
* Check space for itup vector on page
*/
bool
gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete)
gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)
{
unsigned int size = 0, deleted = 0;
unsigned int size = freespace, deleted = 0;
int i;
for (i = 0; i < len; i++)
@@ -82,6 +82,7 @@ gistfitpage(IndexTuple *itvec, int len) {
for(i=0;i<len;i++)
size += IndexTupleSize(itvec[i]) + sizeof(ItemIdData);
/* TODO: Consider fillfactor */
return (size <= GiSTPageSize);
}
@@ -634,3 +635,16 @@ gistNewBuffer(Relation r)
return buffer;
}
Datum
gistoption(PG_FUNCTION_ARGS)
{
#define GIST_DEFAULT_FILLFACTOR 90
#define GIST_MIN_FILLFACTOR 50
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
/* Use index common routine. */
PG_RETURN_BYTEA_P(genam_option(options,
GIST_MIN_FILLFACTOR, GIST_DEFAULT_FILLFACTOR));
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.22 2006/05/19 11:10:25 teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.23 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -376,7 +376,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (curlenaddon)
{
/* insert updated tuples */
if (gistnospace(tempPage, addon, curlenaddon, InvalidOffsetNumber)) {
if (gistnospace(tempPage, addon, curlenaddon, InvalidOffsetNumber, 0)) {
/* there is no space on page to insert tuples */
res = vacuumSplitPage(gv, tempPage, buffer, addon, curlenaddon);
tempPage=NULL; /* vacuumSplitPage() free tempPage */

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.20 2006/05/19 17:15:41 teodor Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.21 2006/07/02 02:23:18 momjian Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -690,7 +690,7 @@ gistContinueInsert(gistIncompleteInsert *insert)
* that wiil be enough space....
*/
if (gistnospace(pages[0], itup, lenitup, *todelete))
if (gistnospace(pages[0], itup, lenitup, *todelete, 0))
{
/* no space left on page, so we must split */

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hashpage.c,v 1.57 2006/03/31 23:32:05 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/hash/hashpage.c,v 1.58 2006/07/02 02:23:18 momjian Exp $
*
* NOTES
* Postgres hash pages look like ordinary relation pages. The opaque
@@ -30,6 +30,7 @@
#include "access/genam.h"
#include "access/hash.h"
#include "catalog/index.h"
#include "miscadmin.h"
#include "storage/lmgr.h"
#include "utils/lsyscache.h"
@@ -231,7 +232,7 @@ _hash_metapinit(Relation rel)
RelationGetDescr(rel)->attrs[0]->atttypmod);
item_width = MAXALIGN(sizeof(IndexTupleData)) + MAXALIGN(data_width) +
sizeof(ItemIdData); /* include the line pointer */
ffactor = (BLCKSZ * 3 / 4) / item_width;
ffactor = BLCKSZ * IndexGetFillFactor(rel) / 100 / item_width;
/* keep to a sane range */
if (ffactor < 10)
ffactor = 10;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hashutil.c,v 1.47 2006/03/05 15:58:21 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/hash/hashutil.c,v 1.48 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -173,3 +173,16 @@ _hash_checkpage(Relation rel, Buffer buf, int flags)
errhint("Please REINDEX it.")));
}
}
Datum
hashoption(PG_FUNCTION_ARGS)
{
#define HASH_MIN_FILLFACTOR 50
#define HASH_DEFAULT_FILLFACTOR 75
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
/* Use index common routine. */
PG_RETURN_BYTEA_P(genam_option(options,
HASH_MIN_FILLFACTOR, HASH_DEFAULT_FILLFACTOR));
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.213 2006/05/28 02:27:08 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.214 2006/07/02 02:23:18 momjian Exp $
*
*
* INTERFACE ROUTINES
@@ -46,9 +46,13 @@
#include "access/xlogutils.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "nodes/parsenodes.h"
#include "parser/parse_clause.h"
#include "pgstat.h"
#include "storage/procarray.h"
#include "utils/catcache.h"
#include "utils/inval.h"
#include "utils/relcache.h"
@@ -3588,3 +3592,59 @@ heap_desc(StringInfo buf, uint8 xl_info, char *rec)
else
appendStringInfo(buf, "UNKNOWN");
}
/*
* Parse options for heaps.
*
* relkind Kind of relation
* options Options as text[]
*/
bytea *
heap_option(char relkind, ArrayType *options)
{
/*
* XXX: What fillfactor should be default?
* overriding databases:
* - Oracle, DB2 = 90%
* - SQL Server = 100%
* non-overriding database:
* - Firebird = 70%
*/
#define HEAP_MIN_FILLFACTOR 50
#define HEAP_DEFAULT_FILLFACTOR 100
int fillfactor;
HeapOption *result;
DefElem kwds[] =
{
{ T_DefElem, "fillfactor" },
};
/*
* parse options
*/
OptionParse(options, lengthof(kwds), kwds, true);
/* 0: fillfactor */
if (kwds[0].arg)
fillfactor = (int) defGetInt64(&kwds[0]);
else
fillfactor = HEAP_DEFAULT_FILLFACTOR;
if (fillfactor < HEAP_MIN_FILLFACTOR || 100 < fillfactor)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("fillfactor=%d should be between %d and 100",
fillfactor, HEAP_MIN_FILLFACTOR)));
}
/*
* build option
*/
result = (HeapOption *)
MemoryContextAlloc(CacheMemoryContext, sizeof(HeapOption));
VARATT_SIZEP(result) = sizeof(HeapOption);
result->fillfactor = fillfactor;
return (bytea *) result;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.61 2006/03/05 15:58:21 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.62 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -102,12 +102,18 @@ RelationGetBufferForTuple(Relation relation, Size len,
{
Buffer buffer = InvalidBuffer;
Page pageHeader;
Size pageFreeSpace;
Size pageFreeSpace,
freespace;
BlockNumber targetBlock,
otherBlock;
bool needLock;
if (relation->rd_options == NULL)
elog(ERROR, "RelationGetBufferForTuple %s IS NULL", RelationGetRelationName(relation));
Assert(relation->rd_options != NULL);
len = MAXALIGN(len); /* be conservative */
freespace = HeapGetPageFreeSpace(relation);
/*
* If we're gonna fail for oversize tuple, do it right away
@@ -146,7 +152,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
* We have no cached target page, so ask the FSM for an initial
* target.
*/
targetBlock = GetPageWithFreeSpace(&relation->rd_node, len);
targetBlock = GetPageWithFreeSpace(&relation->rd_node, len + freespace);
/*
* If the FSM knows nothing of the rel, try the last page before we
@@ -202,7 +208,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
*/
pageHeader = (Page) BufferGetPage(buffer);
pageFreeSpace = PageGetFreeSpace(pageHeader);
if (len <= pageFreeSpace)
if (len + freespace <= pageFreeSpace)
{
/* use this page as future insert target, too */
relation->rd_targblock = targetBlock;
@@ -235,7 +241,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
targetBlock = RecordAndGetPageWithFreeSpace(&relation->rd_node,
targetBlock,
pageFreeSpace,
len);
len + freespace);
}
/*

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.55 2006/05/07 01:21:30 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.56 2006/07/02 02:23:18 momjian Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -21,8 +21,12 @@
#include "access/genam.h"
#include "access/heapam.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "nodes/parsenodes.h"
#include "parser/parse_clause.h"
#include "pgstat.h"
#include "utils/catcache.h"
/* ----------------------------------------------------------------
@@ -260,3 +264,44 @@ systable_endscan(SysScanDesc sysscan)
pfree(sysscan);
}
/*
* Parse options for generic indexes.
*/
bytea *
genam_option(ArrayType *options,
int minFillfactor, int defaultFillfactor)
{
int fillfactor;
IndexOption *result;
DefElem kwds[] =
{
{ T_DefElem, "fillfactor" },
};
/*
* parse options
*/
OptionParse(options, lengthof(kwds), kwds, true);
/* 0: fillfactor */
if (kwds[0].arg)
fillfactor = (int) defGetInt64(&kwds[0]);
else
fillfactor = defaultFillfactor;
if (fillfactor < minFillfactor || 100 < fillfactor)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("fillfactor=%d should be between %d and 100",
fillfactor, minFillfactor)));
/*
* build options
*/
result = (IndexOption *)
MemoryContextAlloc(CacheMemoryContext, sizeof(IndexOption));
VARATT_SIZEP(result) = sizeof(IndexOption);
result->fillfactor = fillfactor;
return (bytea *) result;
}

View File

@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.137 2006/05/08 00:00:09 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.138 2006/07/02 02:23:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/nbtree.h"
#include "miscadmin.h"
@@ -25,6 +26,7 @@ typedef struct
{
/* context data for _bt_checksplitloc */
Size newitemsz; /* size of new item to be inserted */
int fillfactor; /* used when insert at right most */
bool is_leaf; /* T if splitting a leaf page */
bool is_rightmost; /* T if splitting a rightmost page */
@@ -986,14 +988,11 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
* it needs to go into!)
*
* If the page is the rightmost page on its level, we instead try to arrange
* for twice as much free space on the right as on the left. In this way,
* for reserving (100-fillfactor)% of free space on left page. In this way,
* when we are inserting successively increasing keys (consider sequences,
* timestamps, etc) we will end up with a tree whose pages are about 67% full,
* timestamps, etc) we will end up with a tree whose pages are about fillfactor% full,
* instead of the 50% full result that we'd get without this special case.
* (We could bias it even further to make the initially-loaded tree more full.
* But since the steady-state load for a btree is about 70%, we'd likely just
* be making more page-splitting work for ourselves later on, when we start
* seeing updates to existing tuples.)
* This is the same as initially-loaded tree.
*
* We are passed the intended insert position of the new tuple, expressed as
* the offsetnumber of the tuple it must go in front of. (This could be
@@ -1027,6 +1026,7 @@ _bt_findsplitloc(Relation rel,
/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
newitemsz += sizeof(ItemIdData);
state.newitemsz = newitemsz;
state.fillfactor = IndexGetFillFactor(rel);
state.is_leaf = P_ISLEAF(opaque);
state.is_rightmost = P_RIGHTMOST(opaque);
state.have_split = false;
@@ -1157,10 +1157,11 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
if (state->is_rightmost)
{
/*
* On a rightmost page, try to equalize right free space with
* twice the left free space. See comments for _bt_findsplitloc.
* On a rightmost page, try to reserve (100-fillfactor)% of
* free space on left page. See comments for _bt_findsplitloc.
*/
delta = (2 * leftfree) - rightfree;
delta = (state->fillfactor * leftfree)
- ((100 - state->fillfactor) * rightfree);
}
else
{

View File

@@ -56,13 +56,14 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.102 2006/06/27 16:53:02 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.103 2006/07/02 02:23:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/nbtree.h"
#include "access/xlog.h"
#include "miscadmin.h"
@@ -120,6 +121,7 @@ typedef struct BTWriteState
static Page _bt_blnewpage(uint32 level);
static Size _bt_full_threshold(Relation index, Size pagesize, bool leaf);
static BTPageState *_bt_pagestate(BTWriteState *wstate, uint32 level);
static void _bt_slideleft(Page page);
static void _bt_sortaddtup(Page page, Size itemsize,
@@ -327,6 +329,22 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
pfree(page);
}
/*
* The steady-state load factor for btrees is usually estimated at 70%.
* We choose to pack leaf pages to 90% and upper pages to 70% as defaults.
*/
static Size
_bt_full_threshold(Relation index, Size pagesize, bool leaf)
{
int fillfactor = IndexGetFillFactor(index);
if (!leaf)
{
/* XXX: Is this reasonable? */
fillfactor = Max(70, 3 * fillfactor - 200);
}
return pagesize * (100 - fillfactor) / 100;
}
/*
* allocate and initialize a new BTPageState. the returned structure
* is suitable for immediate use by _bt_buildadd.
@@ -347,10 +365,8 @@ _bt_pagestate(BTWriteState *wstate, uint32 level)
state->btps_lastoff = P_HIKEY;
state->btps_level = level;
/* set "full" threshold based on level. See notes at head of file. */
if (level > 0)
state->btps_full = (PageGetPageSize(state->btps_page) * 3) / 10;
else
state->btps_full = PageGetPageSize(state->btps_page) / 10;
state->btps_full = _bt_full_threshold(wstate->index,
PageGetPageSize(state->btps_page), level == 0);
/* no parent level, yet */
state->btps_next = NULL;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.74 2006/05/08 00:00:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.75 2006/07/02 02:23:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1079,3 +1079,16 @@ BTreeShmemInit(void)
else
Assert(found);
}
Datum
btoption(PG_FUNCTION_ARGS)
{
#define BTREE_MIN_FILLFACTOR 50
#define BTREE_DEFAULT_FILLFACTOR 90
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
/* Use index common routine. */
PG_RETURN_BYTEA_P(genam_option(options,
BTREE_MIN_FILLFACTOR, BTREE_DEFAULT_FILLFACTOR));
}

View File

@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.44 2006/04/14 20:27:24 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.45 2006/07/02 02:23:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -337,7 +337,7 @@ _xl_remove_hash_entry(XLogRelDesc *rdesc)
RelationCloseSmgr(&(rdesc->reldata));
memset(rdesc, 0, sizeof(XLogRelDesc));
memset(tpgc, 0, sizeof(FormData_pg_class));
memset(tpgc, 0, CLASS_TUPLE_SIZE);
rdesc->reldata.rd_rel = tpgc;
}