1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-23 03:21:12 +03:00

Add GiST and btree sortsupport routines for range types

For GiST, having a sortsupport function allows building the index
using the "sorted build" method, which is much faster.

For b-tree, the sortsupport routine doesn't give any new
functionality, but speeds up sorting a tiny bit. The difference is not
very significant, about 2% in cursory testing on my laptop, because
the range type comparison function has quite a lot of overhead from
detoasting. In any case, since we have the function for GiST anyway,
we might as well register it for the btree opfamily too.

Author: Bernd Helmle <mailings@oopsware.de>
Discussion: https://www.postgresql.org/message-id/64d324ce2a6d535d3f0f3baeeea7b25beff82ce4.camel@oopsware.de
This commit is contained in:
Heikki Linnakangas
2025-04-02 19:51:28 +03:00
parent ea3f9b6da3
commit e9e7b66044
4 changed files with 74 additions and 1 deletions

View File

@ -43,6 +43,7 @@
#include "utils/date.h"
#include "utils/lsyscache.h"
#include "utils/rangetypes.h"
#include "utils/sortsupport.h"
#include "utils/timestamp.h"
@ -57,6 +58,7 @@ typedef struct RangeIOData
static RangeIOData *get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid,
IOFuncSelector func);
static int range_fast_cmp(Datum a, Datum b, SortSupport ssup);
static char range_parse_flags(const char *flags_str);
static bool range_parse(const char *string, char *flags, char **lbound_str,
char **ubound_str, Node *escontext);
@ -1290,6 +1292,68 @@ range_cmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(cmp);
}
/* Sort support strategy routine */
Datum
range_sortsupport(PG_FUNCTION_ARGS)
{
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
ssup->comparator = range_fast_cmp;
ssup->ssup_extra = NULL;
PG_RETURN_VOID();
}
/* like range_cmp, but uses the new sortsupport interface */
static int
range_fast_cmp(Datum a, Datum b, SortSupport ssup)
{
RangeType *range_a = DatumGetRangeTypeP(a);
RangeType *range_b = DatumGetRangeTypeP(b);
TypeCacheEntry *typcache;
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
int cmp;
/* cache the range info between calls */
if (ssup->ssup_extra == NULL)
{
Assert(RangeTypeGetOid(range_a) == RangeTypeGetOid(range_b));
ssup->ssup_extra =
lookup_type_cache(RangeTypeGetOid(range_a), TYPECACHE_RANGE_INFO);
}
typcache = ssup->ssup_extra;
range_deserialize(typcache, range_a, &lower1, &upper1, &empty1);
range_deserialize(typcache, range_b, &lower2, &upper2, &empty2);
/* For b-tree use, empty ranges sort before all else */
if (empty1 && empty2)
cmp = 0;
else if (empty1)
cmp = -1;
else if (empty2)
cmp = 1;
else
{
cmp = range_cmp_bounds(typcache, &lower1, &lower2);
if (cmp == 0)
cmp = range_cmp_bounds(typcache, &upper1, &upper2);
}
if ((Datum) range_a != a)
pfree(range_a);
if ((Datum) range_b != b)
pfree(range_b);
return cmp;
}
/* inequality operators using the range_cmp function */
Datum
range_lt(PG_FUNCTION_ARGS)

View File

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202504012
#define CATALOG_VERSION_NO 202504021
#endif

View File

@ -283,6 +283,9 @@
amprocrighttype => 'tsquery', amprocnum => '1', amproc => 'tsquery_cmp' },
{ amprocfamily => 'btree/range_ops', amproclefttype => 'anyrange',
amprocrighttype => 'anyrange', amprocnum => '1', amproc => 'range_cmp' },
{ amprocfamily => 'btree/range_ops', amproclefttype => 'anyrange',
amprocrighttype => 'anyrange', amprocnum => '2',
amproc => 'range_sortsupport' },
{ amprocfamily => 'btree/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '1',
amproc => 'multirange_cmp' },
@ -606,6 +609,9 @@
{ amprocfamily => 'gist/range_ops', amproclefttype => 'anyrange',
amprocrighttype => 'anyrange', amprocnum => '7',
amproc => 'range_gist_same' },
{ amprocfamily => 'gist/range_ops', amproclefttype => 'anyrange',
amprocrighttype => 'anyrange', amprocnum => '11',
amproc => 'range_sortsupport' },
{ amprocfamily => 'gist/range_ops', amproclefttype => 'any',
amprocrighttype => 'any', amprocnum => '12',
amproc => 'gist_stratnum_common' },

View File

@ -10855,6 +10855,9 @@
{ oid => '3870', descr => 'less-equal-greater',
proname => 'range_cmp', prorettype => 'int4',
proargtypes => 'anyrange anyrange', prosrc => 'range_cmp' },
{ oid => '8849', descr => 'sort support',
proname => 'range_sortsupport', prorettype => 'void',
proargtypes => 'internal', prosrc => 'range_sortsupport' },
{ oid => '3871',
proname => 'range_lt', prorettype => 'bool',
proargtypes => 'anyrange anyrange', prosrc => 'range_lt' },