mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Implement "fastupdate" support for GIN indexes, in which we try to accumulate
multiple index entries in a holding area before adding them to the main index structure. This helps because bulk insert is (usually) significantly faster than retail insert for GIN. This patch also removes GIN support for amgettuple-style index scans. The API defined for amgettuple is difficult to support with fastupdate, and the previously committed partial-match feature didn't really work with it either. We might eventually figure a way to put back amgettuple support, but it won't happen for 8.4. catversion bumped because of change in GIN's pg_am entry, and because the format of GIN indexes changed on-disk (there's a metapage now, and possibly a pending list). Teodor Sigaev
This commit is contained in:
@ -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.20 2009/01/05 17:14:28 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.21 2009/03/24 20:17:11 tgl Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -57,7 +57,7 @@ initGinState(GinState *state, Relation index)
|
||||
CurrentMemoryContext);
|
||||
|
||||
/*
|
||||
* Check opclass capability to do partial match.
|
||||
* Check opclass capability to do partial match.
|
||||
*/
|
||||
if ( index_getprocid(index, i+1, GIN_COMPARE_PARTIAL_PROC) != InvalidOid )
|
||||
{
|
||||
@ -88,7 +88,7 @@ gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
|
||||
bool isnull;
|
||||
|
||||
/*
|
||||
* First attribute is always int16, so we can safely use any
|
||||
* First attribute is always int16, so we can safely use any
|
||||
* tuple descriptor to obtain first attribute of tuple
|
||||
*/
|
||||
res = index_getattr(tuple, FirstOffsetNumber, ginstate->tupdesc[0],
|
||||
@ -213,6 +213,22 @@ GinInitBuffer(Buffer b, uint32 f)
|
||||
GinInitPage(BufferGetPage(b), f, BufferGetPageSize(b));
|
||||
}
|
||||
|
||||
void
|
||||
GinInitMetabuffer(Buffer b)
|
||||
{
|
||||
GinMetaPageData *metadata;
|
||||
Page page = BufferGetPage(b);
|
||||
|
||||
GinInitPage(page, GIN_META, BufferGetPageSize(b));
|
||||
|
||||
metadata = GinPageGetMeta(page);
|
||||
|
||||
metadata->head = metadata->tail = InvalidBlockNumber;
|
||||
metadata->tailFreeSize = 0;
|
||||
metadata->nPendingPages = 0;
|
||||
metadata->nPendingHeapTuples = 0;
|
||||
}
|
||||
|
||||
int
|
||||
compareEntries(GinState *ginstate, OffsetNumber attnum, Datum a, Datum b)
|
||||
{
|
||||
@ -315,10 +331,26 @@ ginoptions(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum reloptions = PG_GETARG_DATUM(0);
|
||||
bool validate = PG_GETARG_BOOL(1);
|
||||
bytea *result;
|
||||
relopt_value *options;
|
||||
GinOptions *rdopts;
|
||||
int numoptions;
|
||||
static const relopt_parse_elt tab[] = {
|
||||
{"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)}
|
||||
};
|
||||
|
||||
result = default_reloptions(reloptions, validate, RELOPT_KIND_GIN);
|
||||
if (result)
|
||||
PG_RETURN_BYTEA_P(result);
|
||||
PG_RETURN_NULL();
|
||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIN,
|
||||
&numoptions);
|
||||
|
||||
/* if none set, we're done */
|
||||
if (numoptions == 0)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
rdopts = allocateReloptStruct(sizeof(GinOptions), options, numoptions);
|
||||
|
||||
fillRelOptions((void *) rdopts, sizeof(GinOptions), options, numoptions,
|
||||
validate, tab, lengthof(tab));
|
||||
|
||||
pfree(options);
|
||||
|
||||
PG_RETURN_BYTEA_P(rdopts);
|
||||
}
|
||||
|
Reference in New Issue
Block a user