v5-0002-Add-GIST-sortsupport-function-for-range_ops.patch
text/x-patch
Filename: v5-0002-Add-GIST-sortsupport-function-for-range_ops.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v5-0002
Subject: Add GIST sortsupport function for range_ops
| File | + | − |
|---|---|---|
| src/backend/utils/adt/rangetypes_gist.c | 70 | 0 |
| src/include/catalog/pg_amproc.dat | 3 | 0 |
| src/include/catalog/pg_proc.dat | 3 | 0 |
From fb85f80ff416f902fde3d80654dfb61b4479f6ec Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Wed, 10 Jan 2024 15:10:29 +0800
Subject: [PATCH v5 2/2] Add GIST sortsupport function for range_ops
It can facilitate fast GIST index build for range data type.
---
src/backend/utils/adt/rangetypes_gist.c | 70 +++++++++++++++++++++++++
src/include/catalog/pg_amproc.dat | 3 ++
src/include/catalog/pg_proc.dat | 3 ++
3 files changed, 76 insertions(+)
diff --git a/src/backend/utils/adt/rangetypes_gist.c b/src/backend/utils/adt/rangetypes_gist.c
index cb28e985..cb230f39 100644
--- a/src/backend/utils/adt/rangetypes_gist.c
+++ b/src/backend/utils/adt/rangetypes_gist.c
@@ -21,6 +21,7 @@
#include "utils/fmgrprotos.h"
#include "utils/multirangetypes.h"
#include "utils/rangetypes.h"
+#include "utils/sortsupport.h"
/*
* Range class properties used to segregate different classes of ranges in
@@ -177,6 +178,7 @@ static void range_gist_double_sorting_split(TypeCacheEntry *typcache,
static void range_gist_consider_split(ConsiderSplitContext *context,
RangeBound *right_lower, int min_left_count,
RangeBound *left_upper, int max_left_count);
+static int range_gist_cmp(Datum a, Datum b, SortSupport ssup);
static int get_gist_range_class(RangeType *range);
static int single_bound_cmp(const void *a, const void *b, void *arg);
static int interval_cmp_lower(const void *a, const void *b, void *arg);
@@ -773,6 +775,20 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(v);
}
+/*
+ * Sort support routine for fast GiST index build by sorting.
+ */
+Datum
+range_gist_sortsupport(PG_FUNCTION_ARGS)
+{
+ SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
+
+ ssup->comparator = range_gist_cmp;
+ ssup->ssup_extra = NULL;
+
+ PG_RETURN_VOID();
+}
+
/* equality comparator for GiST */
Datum
range_gist_same(PG_FUNCTION_ARGS)
@@ -1693,6 +1709,60 @@ range_gist_consider_split(ConsiderSplitContext *context,
}
}
+/*
+ * GiST sortsupport comparator for ranges.
+ * similar to range_cmp, but range typcache is cached.
+ */
+static int
+range_gist_cmp(Datum a, Datum b, SortSupport ssup)
+{
+ RangeType *range_a = DatumGetRangeTypeP(a);
+ RangeType *range_b = DatumGetRangeTypeP(b);
+ TypeCacheEntry *typcache = ssup->ssup_extra;
+ RangeBound lower1,
+ lower2;
+ RangeBound upper1,
+ upper2;
+ bool empty1,
+ empty2;
+ int result;
+
+ if (typcache == NULL)
+ {
+ Assert(RangeTypeGetOid(range_a) == RangeTypeGetOid(range_b));
+ typcache = lookup_type_cache(RangeTypeGetOid(range_a), TYPECACHE_RANGE_INFO);
+
+ /*
+ * Cache the range info between calls to avoid having to call
+ * lookup_type_cache() for each comparison.
+ */
+ ssup->ssup_extra = typcache;
+ }
+
+ range_deserialize(typcache, range_a, &lower1, &upper1, &empty1);
+ range_deserialize(typcache, range_b, &lower2, &upper2, &empty2);
+
+ if (empty1 && empty2)
+ result = 0;
+ else if (empty1)
+ result = -1;
+ else if (empty2)
+ result = 1;
+ else
+ {
+ result = range_cmp_bounds(typcache, &lower1, &lower2);
+ if (result == 0)
+ result = range_cmp_bounds(typcache, &upper1, &upper2);
+ }
+
+ if ((Datum) range_a != a)
+ pfree(range_a);
+ if ((Datum) range_b != b)
+ pfree(range_b);
+
+ return result;
+}
+
/*
* Find class number for range.
*
diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat
index f639c3a6..71d4bba1 100644
--- a/src/include/catalog/pg_amproc.dat
+++ b/src/include/catalog/pg_amproc.dat
@@ -598,6 +598,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_gist_sortsupport' },
{ amprocfamily => 'gist/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '1',
amproc => 'inet_gist_consistent' },
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 79793927..8b8aa5af 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10577,6 +10577,9 @@
{ oid => '3881', descr => 'GiST support',
proname => 'range_gist_same', prorettype => 'internal',
proargtypes => 'anyrange anyrange internal', prosrc => 'range_gist_same' },
+{ oid => '8849', descr => 'GiST support',
+ proname => 'range_gist_sortsupport', prorettype => 'void',
+ proargtypes => 'internal', prosrc => 'range_gist_sortsupport' },
{ oid => '6154', descr => 'GiST support',
proname => 'multirange_gist_consistent', prorettype => 'bool',
proargtypes => 'internal anymultirange int2 oid internal',
--
2.34.1