* build algorithm for GiST indexes implementation.
*
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
#include "access/genam.h"
#include "access/gist_private.h"
+#include "access/gistxlog.h"
+#include "access/tableam.h"
#include "access/xloginsert.h"
#include "catalog/index.h"
#include "miscadmin.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
#include "storage/bufmgr.h"
#include "storage/smgr.h"
#include "utils/memutils.h"
typedef struct
{
Relation indexrel;
+ Relation heaprel;
GISTSTATE *giststate;
int64 indtuples; /* number of tuples indexed */
* but switches to more efficient buffering build algorithm after a certain
* number of tuples (unless buffering mode is disabled).
*/
-Datum
-gistbuild(PG_FUNCTION_ARGS)
+IndexBuildResult *
+gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
{
- Relation heap = (Relation) PG_GETARG_POINTER(0);
- Relation index = (Relation) PG_GETARG_POINTER(1);
- IndexInfo *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
IndexBuildResult *result;
double reltuples;
GISTBuildState buildstate;
int fillfactor;
buildstate.indexrel = index;
+ buildstate.heaprel = heap;
if (index->rd_options)
{
/* Get buffering mode from the options string */
/*
* Do the heap scan.
*/
- reltuples = IndexBuildHeapScan(heap, index, indexInfo, true,
- gistBuildCallback, (void *) &buildstate);
+ reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
+ gistBuildCallback,
+ (void *) &buildstate, NULL);
/*
* If buffering was used, flush out all the tuples that are still in the
result->heap_tuples = reltuples;
result->index_tuples = (double) buildstate.indtuples;
- PG_RETURN_POINTER(result);
+ return result;
}
/*
* and "auto" values.
*/
void
-gistValidateBufferingOption(char *value)
+gistValidateBufferingOption(const char *value)
{
if (value == NULL ||
(strcmp(value, "on") != 0 &&
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for \"buffering\" option"),
- errdetail("Valid values are \"on\", \"off\", and \"auto\".")));
+ errdetail("Valid values are \"on\", \"off\", and \"auto\".")));
}
}
itupMinSize = (Size) MAXALIGN(sizeof(IndexTupleData));
for (i = 0; i < index->rd_att->natts; i++)
{
- if (index->rd_att->attrs[i]->attlen < 0)
+ if (TupleDescAttr(index->rd_att, i)->attlen < 0)
itupMinSize += VARHDRSZ;
else
- itupMinSize += index->rd_att->attrs[i]->attlen;
+ itupMinSize += TupleDescAttr(index->rd_att, i)->attlen;
}
/* Calculate average and maximal number of index tuples which fit to page */
}
/*
- * Per-tuple callback from IndexBuildHeapScan.
+ * Per-tuple callback for table_index_build_scan.
*/
static void
gistBuildCallback(Relation index,
* locked, we call gistdoinsert directly.
*/
gistdoinsert(index, itup, buildstate->freespace,
- buildstate->giststate);
+ buildstate->giststate, buildstate->heaprel);
}
/* Update tuple count and total size. */
itup, ntup, oldoffnum, &placed_to_blk,
InvalidBuffer,
&splitinfo,
- false);
+ false,
+ buildstate->heaprel);
/*
* If this is a root split, update the root path item kept in memory. This
downlinks, ndownlinks, downlinkoffnum,
InvalidBlockNumber, InvalidOffsetNumber);
- list_free_deep(splitinfo); /* we don't need this anymore */
+ list_free_deep(splitinfo); /* we don't need this anymore */
}
else
UnlockReleaseBuffer(buffer);
* everywhere, so we just pick the first one.
*/
itup = (IndexTuple) PageGetItem(page,
- PageGetItemId(page, FirstOffsetNumber));
+ PageGetItemId(page, FirstOffsetNumber));
blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
UnlockReleaseBuffer(buffer);
buildstate->parentMap = hash_create("gistbuild parent map",
1024,
&hashCtl,
- HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
+ HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
}
static void