From bba81f9d3d4f512280bd55751a450dac6f02d406 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 9 Jan 2026 20:31:43 +0200 Subject: [PATCH] Inline ginCompareAttEntries for speed It is called in tight loops during GIN index build. Author: David Geier Discussion: https://www.postgresql.org/message-id/5d366878-2007-4d31-861e-19294b7a583b@gmail.com --- src/backend/access/gin/ginutil.c | 38 --------------------------- src/include/access/gin_private.h | 44 +++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index a546cac18d3..d205093e21d 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -387,44 +387,6 @@ GinInitMetabuffer(Buffer b) ((char *) metadata + sizeof(GinMetaPageData)) - (char *) page; } -/* - * Compare two keys of the same index column - */ -int -ginCompareEntries(GinState *ginstate, OffsetNumber attnum, - Datum a, GinNullCategory categorya, - Datum b, GinNullCategory categoryb) -{ - /* if not of same null category, sort by that first */ - if (categorya != categoryb) - return (categorya < categoryb) ? -1 : 1; - - /* all null items in same category are equal */ - 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)); -} - -/* - * Compare two keys of possibly different index columns - */ -int -ginCompareAttEntries(GinState *ginstate, - OffsetNumber attnuma, Datum a, GinNullCategory categorya, - OffsetNumber attnumb, Datum b, GinNullCategory categoryb) -{ - /* attribute number is the first sort key */ - if (attnuma != attnumb) - return (attnuma < attnumb) ? -1 : 1; - - return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb); -} - - /* * Support for sorting key datums in ginExtractEntries * diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index b33f7cec5b4..e155045ce8a 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -97,12 +97,6 @@ extern Buffer GinNewBuffer(Relation index); extern void GinInitBuffer(Buffer b, uint32 f); extern void GinInitPage(Page page, uint32 f, Size pageSize); extern void GinInitMetabuffer(Buffer b); -extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, - Datum a, GinNullCategory categorya, - Datum b, GinNullCategory categoryb); -extern int ginCompareAttEntries(GinState *ginstate, - OffsetNumber attnuma, Datum a, GinNullCategory categorya, - OffsetNumber attnumb, Datum b, GinNullCategory categoryb); extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories); @@ -502,6 +496,44 @@ ginCompareItemPointers(ItemPointer a, ItemPointer b) return pg_cmp_u64(ia, ib); } +/* + * Compare two keys of the same index column + */ +static inline int +ginCompareEntries(GinState *ginstate, OffsetNumber attnum, + Datum a, GinNullCategory categorya, + Datum b, GinNullCategory categoryb) +{ + /* if not of same null category, sort by that first */ + if (categorya != categoryb) + return (categorya < categoryb) ? -1 : 1; + + /* all null items in same category are equal */ + 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)); +} + +/* + * Compare two keys of possibly different index columns + */ +static inline int +ginCompareAttEntries(GinState *ginstate, + OffsetNumber attnuma, Datum a, GinNullCategory categorya, + OffsetNumber attnumb, Datum b, GinNullCategory categoryb) +{ + /* attribute number is the first sort key */ + if (attnuma != attnumb) + return (attnuma < attnumb) ? -1 : 1; + + return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb); + +} + extern int ginTraverseLock(Buffer buffer, bool searchMode); #endif /* GIN_PRIVATE_H */