v1-0002-Optimized-comparison-functions.patch
text/x-patch
Filename: v1-0002-Optimized-comparison-functions.patch
Type: text/x-patch
Part: 6
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0002
Subject: Optimized comparison functions
| File | + | − |
|---|---|---|
| src/backend/access/gin/ginutil.c | 12 | 7 |
| src/include/access/gin_private.h | 15 | 4 |
From eb7fe3763b31d30d48ebbd4934085fe70315249a Mon Sep 17 00:00:00 2001
From: David Geier <geidav.pg@gmail.com>
Date: Mon, 10 Nov 2025 13:35:01 +0100
Subject: [PATCH v1 2/8] Optimized comparison functions
---
src/backend/access/gin/ginutil.c | 19 ++++++++++++-------
src/include/access/gin_private.h | 19 +++++++++++++++----
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index d205093e21d..f4139effd6e 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -114,6 +114,7 @@ initGinState(GinState *state, Relation index)
for (i = 0; i < origTupdesc->natts; i++)
{
Form_pg_attribute attr = TupleDescAttr(origTupdesc, i);
+ FunctionCallInfoBaseData *fci = &state->compareFnCallInfo[i].fcinfo;
if (state->oneCol)
state->tupdesc[i] = state->origTupdesc;
@@ -222,6 +223,10 @@ initGinState(GinState *state, Relation index)
state->supportCollation[i] = index->rd_indcollation[i];
else
state->supportCollation[i] = DEFAULT_COLLATION_OID;
+
+ InitFunctionCallInfoData(*fci, &state->compareFn[i], 2, state->supportCollation[i], NULL, NULL);
+ fci->args[0].isnull = false;
+ fci->args[1].isnull = false;
}
}
@@ -402,8 +407,7 @@ typedef struct
typedef struct
{
- FmgrInfo *cmpDatumFunc;
- Oid collation;
+ FunctionCallInfoBaseData *cmpFuncInfo;
bool haveDups;
} cmpEntriesArg;
@@ -425,9 +429,11 @@ cmpEntries(const void *a, const void *b, void *arg)
else if (bb->isnull)
res = -1; /* not-NULL "<" NULL */
else
- res = DatumGetInt32(FunctionCall2Coll(data->cmpDatumFunc,
- data->collation,
- aa->datum, bb->datum));
+ {
+ data->cmpFuncInfo->args[0].value = aa->datum;
+ data->cmpFuncInfo->args[1].value = bb->datum;
+ res = DatumGetInt32(FunctionCallInvoke(data->cmpFuncInfo));
+ }
/*
* Detect if we have any duplicates. If there are equal keys, qsort must
@@ -518,8 +524,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
keydata[i].isnull = nullFlags[i];
}
- arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
- arg.collation = ginstate->supportCollation[attnum - 1];
+ arg.cmpFuncInfo = &ginstate->compareFnCallInfo[attnum - 1].fcinfo;
arg.haveDups = false;
qsort_arg(keydata, *nentries, sizeof(keyEntryData),
cmpEntries, &arg);
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index e155045ce8a..7cf19c8a5dc 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -51,6 +51,11 @@ typedef struct GinOptions
#define GIN_SHARE BUFFER_LOCK_SHARE
#define GIN_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
+typedef union CompareFuncCallInfoData
+{
+ FunctionCallInfoBaseData fcinfo;
+ char fcinfo_data[SizeForFunctionCallInfo(2)];
+} CompareFuncCallInfoData;
/*
* GinState: working data structure describing the index being worked on
@@ -77,6 +82,10 @@ typedef struct GinState
/*
* Per-index-column opclass support functions
*/
+
+
+ CompareFuncCallInfoData compareFnCallInfo[INDEX_MAX_KEYS];
+
FmgrInfo compareFn[INDEX_MAX_KEYS];
FmgrInfo extractValueFn[INDEX_MAX_KEYS];
FmgrInfo extractQueryFn[INDEX_MAX_KEYS];
@@ -504,6 +513,8 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
Datum a, GinNullCategory categorya,
Datum b, GinNullCategory categoryb)
{
+ FunctionCallInfoBaseData *fci;
+
/* if not of same null category, sort by that first */
if (categorya != categoryb)
return (categorya < categoryb) ? -1 : 1;
@@ -512,10 +523,10 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
if (categorya != GIN_CAT_NORM_KEY)
return 0;
- /* both not null, so safe to call the compareFn */
- return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
- ginstate->supportCollation[attnum - 1],
- a, b));
+ fci = &ginstate->compareFnCallInfo[attnum - 1].fcinfo;
+ fci->args[0].value = a;
+ fci->args[1].value = b;
+ return DatumGetInt32(FunctionCallInvoke(fci));
}
/*
--
2.51.0