From 99459d749505d98b1ba2b93398df46f50fd3a963 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 10 Jun 2019 11:54:59 +0500 Subject: [PATCH 3/3] Function relopt for gist build --- src/backend/access/common/reloptions.c | 12 ++++++ src/backend/access/gist/gistbuild.c | 56 ++++++++++++++++++++++++++ src/backend/access/gist/gistutil.c | 3 +- src/include/access/gist_private.h | 2 + 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 5325dd3f61..698bc1a1aa 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -491,6 +491,18 @@ static relopt_enum enumRelOpts[] = static relopt_string stringRelOpts[] = { + { + { + "fast_build_sort_function", + "Function for presorting data instead of usual penalty\\split inserts", + RELOPT_KIND_GIST, + AccessExclusiveLock + }, + 0, + true, + gistValidateBuildFuncOption, + NULL + }, /* list terminator */ {{NULL}} }; diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 0df03c8c36..02fe1ac1d0 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -22,8 +22,10 @@ #include "access/tableam.h" #include "access/xloginsert.h" #include "catalog/index.h" +#include "catalog/pg_type.h" #include "miscadmin.h" #include "optimizer/optimizer.h" +#include "parser/parse_func.h" #include "storage/bufmgr.h" #include "storage/smgr.h" #include "utils/memutils.h" @@ -306,6 +308,8 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) Oid SortSupportFnOids[INDEX_MAX_KEYS]; bool hasallsortsupports = true; int keyscount = IndexRelationGetNumberOfKeyAttributes(index); + Oid firstsortduncoid; + bool havefirstsortfn = false; buildstate.indexrel = index; buildstate.heaprel = heap; @@ -323,6 +327,16 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) else buildstate.bufferingMode = GIST_BUFFERING_AUTO; + if (options->vl_len_ > offsetof(GiSTOptions, buildSortFunctionOffset) && + options->buildSortFunctionOffset > 0) + { + char *sortFuncName = (char *) options + options->buildSortFunctionOffset; + Oid argList[1] = {INTERNALOID}; + List *namelist = stringToQualifiedNameList(sortFuncName); + firstsortduncoid = LookupFuncName(namelist, 1, argList, false); + havefirstsortfn = true; + } + fillfactor = options->fillfactor; } else @@ -339,6 +353,11 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) for (i = 0; i < keyscount; i++) { + if (i == 0 && havefirstsortfn) + { + SortSupportFnOids[i] = firstsortduncoid; + continue; + } SortSupportFnOids[i] = index_getprocid(index, i + 1, GIST_SORTSUPPORT_PROC); if (!OidIsValid(SortSupportFnOids[i])) { @@ -446,6 +465,43 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) } /* +<<<<<<< HEAD +======= + * Validator for "buffering" reloption on GiST indexes. Allows "on", "off" + * and "auto" values. + */ +void +gistValidateBufferingOption(const char *value) +{ + if (value == NULL || + (strcmp(value, "on") != 0 && + strcmp(value, "off") != 0 && + strcmp(value, "auto") != 0)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for \"buffering\" option"), + errdetail("Valid values are \"on\", \"off\", and \"auto\"."))); + } +} + +/* + * Validator for "fast_build_sort_function" reloption on GiST indexes. Allows function name + */ +void +gistValidateBuildFuncOption(const char *value) +{ + Oid argList[1] = {INTERNALOID}; + List *namelist; + if (value == NULL) + return; + namelist = stringToQualifiedNameList(value); + /* LookupFuncName will fail if function is not existent */ + LookupFuncName(namelist, 1, argList, false); +} + +/* +>>>>>>> function relopt for gist build * Attempt to switch to buffering mode. * * If there is not enough memory for buffering build, sets bufferingMode diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index dfc2a7d36c..17d9fe4806 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -925,7 +925,8 @@ gistoptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)}, - {"buffering", RELOPT_TYPE_ENUM, offsetof(GiSTOptions, buffering_mode)} + {"buffering", RELOPT_TYPE_ENUM, offsetof(GiSTOptions, buffering_mode)}, + {"fast_build_sort_function", RELOPT_TYPE_STRING, offsetof(GiSTOptions, buildSortFunctionOffset)} }; return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 89f77ddcae..324dbeb815 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -396,6 +396,7 @@ typedef struct GiSTOptions int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ GistOptBufferingMode buffering_mode; /* buffering build mode */ + int buildSortFunctionOffset; /* used buffering sort function */ } GiSTOptions; /* gist.c */ @@ -543,6 +544,7 @@ extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup, extern IndexBuildResult *gistbuild(Relation heap, Relation index, struct IndexInfo *indexInfo); extern void gistValidateBufferingOption(const char *value); +extern void gistValidateBuildFuncOption(const char *value); /* gistbuildbuffers.c */ extern GISTBuildBuffers *gistInitBuildBuffers(int pagesPerBuffer, int levelStep, -- 2.21.1 (Apple Git-122.3)