0001-function-relopt-for-gist-build.patch
application/octet-stream
Filename: 0001-function-relopt-for-gist-build.patch
Type: application/octet-stream
Part: 0
Message:
Yet another fast GiST build
Patch
Format: format-patch
Series: patch 0001
Subject: function relopt for gist build
| File | + | − |
|---|---|---|
| src/backend/access/common/reloptions.c | 12 | 0 |
| src/backend/access/gist/gistbuild.c | 30 | 0 |
| src/backend/access/gist/gistutil.c | 2 | 1 |
| src/include/access/gist_private.h | 2 | 0 |
From 6e1a942432f7aa43555c58e882dc404d44554e51 Mon Sep 17 00:00:00 2001
From: Andrey <amborodin@acm.org>
Date: Mon, 10 Jun 2019 11:54:59 +0500
Subject: [PATCH 1/3] function relopt for gist build
---
src/backend/access/common/reloptions.c | 12 +++++++++++
src/backend/access/gist/gistbuild.c | 30 ++++++++++++++++++++++++++
src/backend/access/gist/gistutil.c | 3 ++-
src/include/access/gist_private.h | 2 ++
4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 4d0d24be0b..cd9aa97437 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -450,6 +450,18 @@ static relopt_string stringRelOpts[] =
gistValidateBufferingOption,
"auto"
},
+ {
+ {
+ "fast_build_sort_function",
+ "Function for presorting data instead of usual penalty\\split inserts",
+ RELOPT_KIND_GIST,
+ AccessExclusiveLock
+ },
+ 0,
+ true,
+ gistValidateBuildFuncOption,
+ NULL
+ },
{
{
"check_option",
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index ecef0ff072..e7112590b8 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -22,12 +22,15 @@
#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"
#include "utils/rel.h"
+#include "utils/regproc.h"
/* Step of index tuples for check whether to switch to buffering build mode */
#define BUFFERING_MODE_SWITCH_CHECK_STEP 256
@@ -74,6 +77,7 @@ typedef struct
HTAB *parentMap;
GistBufferingMode bufferingMode;
+ FmgrInfo sortFn;
} GISTBuildState;
/* prototypes for private functions */
@@ -125,6 +129,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
buildstate.indexrel = index;
buildstate.heaprel = heap;
+ buildstate.sortFn.fn_oid = InvalidOid;
if (index->rd_options)
{
/* Get buffering mode from the options string */
@@ -138,6 +143,16 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
else
buildstate.bufferingMode = GIST_BUFFERING_AUTO;
+ if (options->vl_len_ > offsetof(GiSTOptions, buildSortFunctionOffset) &&
+ options->bufferingModeOffset > 0)
+ {
+ char *sortFuncName = (char *) options + options->buildSortFunctionOffset;
+ Oid argList[1] = {INTERNALOID};
+ List *namelist = stringToQualifiedNameList(sortFuncName);
+ Oid sortFuncOid = LookupFuncName(namelist, 1, argList, false);
+ fmgr_info(sortFuncOid, &buildstate.sortFn);
+ }
+
fillfactor = options->fillfactor;
}
else
@@ -255,6 +270,21 @@ gistValidateBufferingOption(const char *value)
}
}
+/*
+ * 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);
+}
+
/*
* Attempt to switch to buffering mode.
*
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index 49df05653b..6e2ff95b5c 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -895,7 +895,8 @@ gistoptions(Datum reloptions, bool validate)
int numoptions;
static const relopt_parse_elt tab[] = {
{"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)},
- {"buffering", RELOPT_TYPE_STRING, offsetof(GiSTOptions, bufferingModeOffset)}
+ {"buffering", RELOPT_TYPE_STRING, offsetof(GiSTOptions, bufferingModeOffset)},
+ {"fast_build_sort_function", RELOPT_TYPE_STRING, offsetof(GiSTOptions, buildSortFunctionOffset)}
};
options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIST,
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index f80694bf9a..b4b6883f6d 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -386,6 +386,7 @@ typedef struct GiSTOptions
int32 vl_len_; /* varlena header (do not touch directly!) */
int fillfactor; /* page fill factor in percent (0..100) */
int bufferingModeOffset; /* use buffering build? */
+ int buildSortFunctionOffset; /* used buffering sort function */
} GiSTOptions;
/* gist.c */
@@ -531,6 +532,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.20.1