From d72845dab91e3f1aa9e8f751ce994c8eec7250ff Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Sat, 3 Oct 2020 21:08:54 +0500 Subject: [PATCH v3] Sortsupport for sorting GiST build for gist_btree types --- contrib/btree_gist/Makefile | 2 +- contrib/btree_gist/btree_bit.c | 32 ++++ contrib/btree_gist/btree_bytea.c | 33 +++- contrib/btree_gist/btree_cash.c | 75 +++++++++ contrib/btree_gist/btree_date.c | 35 ++++ contrib/btree_gist/btree_enum.c | 70 ++++++++ contrib/btree_gist/btree_float4.c | 71 ++++++++ contrib/btree_gist/btree_float8.c | 79 +++++++++ contrib/btree_gist/btree_gist--1.6--1.7.sql | 176 ++++++++++++++++++++ contrib/btree_gist/btree_gist.control | 2 +- contrib/btree_gist/btree_gist.h | 1 + contrib/btree_gist/btree_inet.c | 81 +++++++++ contrib/btree_gist/btree_int2.c | 70 ++++++++ contrib/btree_gist/btree_int4.c | 70 ++++++++ contrib/btree_gist/btree_int8.c | 75 ++++++++- contrib/btree_gist/btree_macaddr.c | 42 +++++ contrib/btree_gist/btree_macaddr8.c | 41 +++++ contrib/btree_gist/btree_numeric.c | 31 ++++ contrib/btree_gist/btree_oid.c | 71 ++++++++ contrib/btree_gist/btree_text.c | 33 ++++ contrib/btree_gist/btree_time.c | 34 ++++ contrib/btree_gist/btree_ts.c | 33 ++++ contrib/btree_gist/btree_uuid.c | 33 ++++ src/backend/access/gist/gistvalidate.c | 1 + 24 files changed, 1187 insertions(+), 4 deletions(-) create mode 100644 contrib/btree_gist/btree_gist--1.6--1.7.sql diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile index e92d974a1a..a1f818f71e 100644 --- a/contrib/btree_gist/Makefile +++ b/contrib/btree_gist/Makefile @@ -32,7 +32,7 @@ EXTENSION = btree_gist DATA = btree_gist--1.0--1.1.sql \ btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql \ btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.sql \ - btree_gist--1.5--1.6.sql + btree_gist--1.5--1.6.sql btree_gist--1.6--1.7.sql PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes" REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \ diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c index 2225244ded..8885914035 100644 --- a/contrib/btree_gist/btree_bit.c +++ b/contrib/btree_gist/btree_bit.c @@ -19,6 +19,7 @@ PG_FUNCTION_INFO_V1(gbt_bit_picksplit); PG_FUNCTION_INFO_V1(gbt_bit_consistent); PG_FUNCTION_INFO_V1(gbt_bit_penalty); PG_FUNCTION_INFO_V1(gbt_bit_same); +PG_FUNCTION_INFO_V1(gbt_bit_sortsupport); /* define for comparison */ @@ -209,3 +210,34 @@ gbt_bit_penalty(PG_FUNCTION_ARGS) PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo)); } + +static int +gbt_bit_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + return DatumGetInt32(DirectFunctionCall2(byteacmp, + PointerGetDatum(a), + PointerGetDatum(b))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_bit_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_bit_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_bit_cmp_sort; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c index 6b005f0157..9e3752e90c 100644 --- a/contrib/btree_gist/btree_bytea.c +++ b/contrib/btree_gist/btree_bytea.c @@ -18,6 +18,7 @@ PG_FUNCTION_INFO_V1(gbt_bytea_picksplit); PG_FUNCTION_INFO_V1(gbt_bytea_consistent); PG_FUNCTION_INFO_V1(gbt_bytea_penalty); PG_FUNCTION_INFO_V1(gbt_bytea_same); +PG_FUNCTION_INFO_V1(gbt_bytea_sortsupport); /* define for comparison */ @@ -87,7 +88,7 @@ static const gbtree_vinfo tinfo = /************************************************** - * Text ops + * Bytea ops **************************************************/ @@ -168,3 +169,33 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS) PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo)); } + +static int +gbt_bytea_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + return DatumGetInt32(DirectFunctionCall2(byteacmp, + PointerGetDatum(a), + PointerGetDatum(b))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_bytea_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_bytea_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_bytea_cmp_sort; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c index dfa23224b6..558c5eb325 100644 --- a/contrib/btree_gist/btree_cash.c +++ b/contrib/btree_gist/btree_cash.c @@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_cash_consistent); PG_FUNCTION_INFO_V1(gbt_cash_distance); PG_FUNCTION_INFO_V1(gbt_cash_penalty); PG_FUNCTION_INFO_V1(gbt_cash_same); +PG_FUNCTION_INFO_V1(gbt_cash_sortsupport); static bool gbt_cashgt(const void *a, const void *b, FmgrInfo *flinfo) @@ -216,3 +217,77 @@ gbt_cash_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_cash_cmp(Datum a, Datum b, SortSupport ssup) +{ + cashKEY *ia = (cashKEY *) DatumGetPointer(a); + cashKEY *ib = (cashKEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_cash_abbrev_convert(Datum original, SortSupport ssup) +{ + cashKEY *b1 = (cashKEY *) DatumGetPointer(original); + int64 z = b1->lower; + +#if SIZEOF_DATUM == 8 + return (Datum) z; +#else + return (Datum) (z >> 32); +#endif +} + +static int +gbt_cash_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_cash_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_cash_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_cash_cmp_abbrev; + ssup->abbrev_converter = gbt_cash_abbrev_convert; + ssup->abbrev_abort = gbt_cash_abbrev_abort; + ssup->abbrev_full_comparator = gbt_cash_cmp; + } + else + { + ssup->comparator = gbt_cash_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c index 455a265a49..7e55d6b997 100644 --- a/contrib/btree_gist/btree_date.c +++ b/contrib/btree_gist/btree_date.c @@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_date_consistent); PG_FUNCTION_INFO_V1(gbt_date_distance); PG_FUNCTION_INFO_V1(gbt_date_penalty); PG_FUNCTION_INFO_V1(gbt_date_same); +PG_FUNCTION_INFO_V1(gbt_date_sortsupport); static bool gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo) @@ -257,3 +258,37 @@ gbt_date_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_date_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + dateKEY *ia = (dateKEY *) PointerGetDatum(a); + dateKEY *ib = (dateKEY *) PointerGetDatum(b); + + return DatumGetInt32(DirectFunctionCall2(date_cmp, + DateADTGetDatum(ia->lower), + DateADTGetDatum(ib->lower))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_date_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_date_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_date_cmp_sort; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c index d4dc38a38e..404117a201 100644 --- a/contrib/btree_gist/btree_enum.c +++ b/contrib/btree_gist/btree_enum.c @@ -26,6 +26,7 @@ PG_FUNCTION_INFO_V1(gbt_enum_picksplit); PG_FUNCTION_INFO_V1(gbt_enum_consistent); PG_FUNCTION_INFO_V1(gbt_enum_penalty); PG_FUNCTION_INFO_V1(gbt_enum_same); +PG_FUNCTION_INFO_V1(gbt_enum_sortsupport); static bool @@ -183,3 +184,72 @@ gbt_enum_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_enum_cmp(Datum a, Datum b, SortSupport ssup) +{ + oidKEY *ia = (oidKEY *) DatumGetPointer(a); + oidKEY *ib = (oidKEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_enum_abbrev_convert(Datum original, SortSupport ssup) +{ + oidKEY *b1 = (oidKEY *) DatumGetPointer(original); + Oid z = b1->lower; + + return (Datum) z; +} + +static int +gbt_enum_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_enum_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_enum_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_enum_cmp_abbrev; + ssup->abbrev_converter = gbt_enum_abbrev_convert; + ssup->abbrev_abort = gbt_enum_abbrev_abort; + ssup->abbrev_full_comparator = gbt_enum_cmp; + } + else + { + ssup->comparator = gbt_enum_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c index 3604c73313..d836d62bb1 100644 --- a/contrib/btree_gist/btree_float4.c +++ b/contrib/btree_gist/btree_float4.c @@ -23,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_float4_consistent); PG_FUNCTION_INFO_V1(gbt_float4_distance); PG_FUNCTION_INFO_V1(gbt_float4_penalty); PG_FUNCTION_INFO_V1(gbt_float4_same); +PG_FUNCTION_INFO_V1(gbt_float4_sortsupport); static bool gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo) @@ -209,3 +210,73 @@ gbt_float4_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + + +static int +gbt_float4_cmp(Datum a, Datum b, SortSupport ssup) +{ + float4KEY *ia = (float4KEY *) DatumGetPointer(a); + float4KEY *ib = (float4KEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_float4_abbrev_convert(Datum original, SortSupport ssup) +{ + float4KEY *b1 = (float4KEY *) DatumGetPointer(original); + float4 z = b1->lower; + + return (Datum) Float4GetDatum(z); +} + +static int +gbt_float4_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (DatumGetFloat4(z1) > DatumGetFloat4(z2)) + return 1; + else if (DatumGetFloat4(z1) < DatumGetFloat4(z2)) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_float4_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_float4_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_float4_cmp_abbrev; + ssup->abbrev_converter = gbt_float4_abbrev_convert; + ssup->abbrev_abort = gbt_float4_abbrev_abort; + ssup->abbrev_full_comparator = gbt_float4_cmp; + } + else + { + ssup->comparator = gbt_float4_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c index 10a5262aaa..8eb8a93710 100644 --- a/contrib/btree_gist/btree_float8.c +++ b/contrib/btree_gist/btree_float8.c @@ -23,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_float8_consistent); PG_FUNCTION_INFO_V1(gbt_float8_distance); PG_FUNCTION_INFO_V1(gbt_float8_penalty); PG_FUNCTION_INFO_V1(gbt_float8_same); +PG_FUNCTION_INFO_V1(gbt_float8_sortsupport); static bool @@ -216,3 +217,81 @@ gbt_float8_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_float8_cmp(Datum a, Datum b, SortSupport ssup) +{ + float8KEY *ia = (float8KEY *) DatumGetPointer(a); + float8KEY *ib = (float8KEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_float8_abbrev_convert(Datum original, SortSupport ssup) +{ + float8KEY *b1 = (float8KEY *) DatumGetPointer(original); + float8 z = b1->lower; + +#if SIZEOF_DATUM == 8 + return (Datum) Float8GetDatum(z); +#else + return (Datum) 0; +#endif +} + +static int +gbt_float8_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ +#if SIZEOF_DATUM == 8 + if (DatumGetFloat8(z1) > DatumGetFloat8(z2)) + return 1; + else if (DatumGetFloat8(z1) < DatumGetFloat8(z2)) + return -1; + else + return 0; +#else + return 0; +#endif +} + +static bool +gbt_float8_abbrev_abort(int memtupcount, SortSupport ssup) +{ +#if SIZEOF_DATUM == 8 + return false; +#else + return true; +#endif +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_float8_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_float8_cmp_abbrev; + ssup->abbrev_converter = gbt_float8_abbrev_convert; + ssup->abbrev_abort = gbt_float8_abbrev_abort; + ssup->abbrev_full_comparator = gbt_float8_cmp; + } + else + { + ssup->comparator = gbt_float8_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_gist--1.6--1.7.sql b/contrib/btree_gist/btree_gist--1.6--1.7.sql new file mode 100644 index 0000000000..bd98a4758e --- /dev/null +++ b/contrib/btree_gist/btree_gist--1.6--1.7.sql @@ -0,0 +1,176 @@ +/* contrib/btree_gist/btree_gist--1.6--1.7.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.7'" to load this file. \quit + + +CREATE FUNCTION gbt_int8_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD + FUNCTION 11 (int8, int8) gbt_int8_sortsupport (internal) ; + +CREATE FUNCTION gbt_int4_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD + FUNCTION 11 (int4, int4) gbt_int4_sortsupport (internal) ; + +CREATE FUNCTION gbt_int2_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD + FUNCTION 11 (int2, int2) gbt_int2_sortsupport (internal) ; + +CREATE FUNCTION gbt_float8_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD + FUNCTION 11 (float8, float8) gbt_float8_sortsupport (internal) ; + +CREATE FUNCTION gbt_float4_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD + FUNCTION 11 (float4, float4) gbt_float4_sortsupport (internal) ; + +CREATE FUNCTION gbt_enum_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD + FUNCTION 11 (anyenum, anyenum) gbt_enum_sortsupport (internal) ; + +CREATE FUNCTION gbt_oid_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD + FUNCTION 11 (oid, oid) gbt_oid_sortsupport (internal) ; + +CREATE FUNCTION gbt_cash_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD + FUNCTION 11 (money, money) gbt_cash_sortsupport (internal) ; + +CREATE FUNCTION gbt_inet_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD + FUNCTION 11 (inet, inet) gbt_inet_sortsupport (internal) ; + + +CREATE FUNCTION gbt_macad_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD + FUNCTION 11 (macaddr, macaddr) gbt_macad_sortsupport (internal) ; + +CREATE FUNCTION gbt_macad8_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_macaddr8_ops USING gist ADD + FUNCTION 11 (macaddr8, macaddr8) gbt_macad8_sortsupport (internal) ; + +CREATE FUNCTION gbt_numeric_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD + FUNCTION 11 (numeric, numeric) gbt_numeric_sortsupport (internal) ; + +CREATE FUNCTION gbt_uuid_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_uuid_ops USING gist ADD + FUNCTION 11 (uuid, uuid) gbt_uuid_sortsupport (internal) ; + +CREATE FUNCTION gbt_ts_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD + FUNCTION 11 (timestamp, timestamp) gbt_ts_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (timestamptz, timestamptz) gbt_ts_sortsupport (internal) ; + +CREATE FUNCTION gbt_text_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_text_ops USING gist ADD + FUNCTION 11 (text, text) gbt_text_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (text, text) gbt_text_sortsupport (internal) ; + +CREATE FUNCTION gbt_time_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_time_ops USING gist ADD + FUNCTION 11 (time, time) gbt_time_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (time, time) gbt_time_sortsupport (internal) ; + +CREATE FUNCTION gbt_bytea_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD + FUNCTION 11 (bytea, bytea) gbt_bytea_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (bytea, bytea) gbt_bytea_sortsupport (internal) ; + +CREATE FUNCTION gbt_date_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_date_ops USING gist ADD + FUNCTION 11 (date, date) gbt_date_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (date, date) gbt_date_sortsupport (internal) ; + +CREATE FUNCTION gbt_bit_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT; + +ALTER OPERATOR FAMILY gist_date_ops USING gist ADD + FUNCTION 11 (bit, bit) gbt_bit_sortsupport (internal) ; + +ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD + FUNCTION 11 (bit, bit) gbt_bit_sortsupport (internal) ; diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control index e5c41fe8f3..fa9171a80a 100644 --- a/contrib/btree_gist/btree_gist.control +++ b/contrib/btree_gist/btree_gist.control @@ -1,6 +1,6 @@ # btree_gist extension comment = 'support for indexing common datatypes in GiST' -default_version = '1.6' +default_version = '1.7' module_pathname = '$libdir/btree_gist' relocatable = true trusted = true diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h index 14c7c8ee19..35ad287ed3 100644 --- a/contrib/btree_gist/btree_gist.h +++ b/contrib/btree_gist/btree_gist.h @@ -6,6 +6,7 @@ #include "access/nbtree.h" #include "fmgr.h" +#include "utils/sortsupport.h" #define BtreeGistNotEqualStrategyNumber 6 diff --git a/contrib/btree_gist/btree_inet.c b/contrib/btree_gist/btree_inet.c index e4b3a946b2..31635fc40c 100644 --- a/contrib/btree_gist/btree_inet.c +++ b/contrib/btree_gist/btree_inet.c @@ -24,6 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_inet_picksplit); PG_FUNCTION_INFO_V1(gbt_inet_consistent); PG_FUNCTION_INFO_V1(gbt_inet_penalty); PG_FUNCTION_INFO_V1(gbt_inet_same); +PG_FUNCTION_INFO_V1(gbt_inet_sortsupport); static bool @@ -186,3 +187,83 @@ gbt_inet_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_inet_cmp(Datum a, Datum b, SortSupport ssup) +{ + inetKEY *ia = (inetKEY *) DatumGetPointer(a); + inetKEY *ib = (inetKEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_inet_abbrev_convert(Datum original, SortSupport ssup) +{ + inetKEY *b1 = (inetKEY *) DatumGetPointer(original); + double z = b1->lower; + +#if SIZEOF_DATUM == 8 + return (Datum) Float8GetDatum(z); +#else + return (Datum) Float4GetDatum((float) z); +#endif +} + +static int +gbt_inet_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ +#if SIZEOF_DATUM == 8 + if (DatumGetFloat8(z1) > DatumGetFloat8(z2)) + return 1; + else if (DatumGetFloat8(z1) < DatumGetFloat8(z2)) + return -1; + else + return 0; +#else + if (DatumGetFloat4(z1) > DatumGetFloat4(z2)) + return 1; + else if (DatumGetFloat4(z1) < DatumGetFloat4(z2)) + return -1; + else + return 0; +#endif +} + +static bool +gbt_inet_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_inet_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_inet_cmp_abbrev; + ssup->abbrev_converter = gbt_inet_abbrev_convert; + ssup->abbrev_abort = gbt_inet_abbrev_abort; + ssup->abbrev_full_comparator = gbt_inet_cmp; + } + else + { + ssup->comparator = gbt_inet_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c index a91b95ff39..abcff85a93 100644 --- a/contrib/btree_gist/btree_int2.c +++ b/contrib/btree_gist/btree_int2.c @@ -24,6 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_int2_consistent); PG_FUNCTION_INFO_V1(gbt_int2_distance); PG_FUNCTION_INFO_V1(gbt_int2_penalty); PG_FUNCTION_INFO_V1(gbt_int2_same); +PG_FUNCTION_INFO_V1(gbt_int2_sortsupport); static bool gbt_int2gt(const void *a, const void *b, FmgrInfo *flinfo) @@ -214,3 +215,72 @@ gbt_int2_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_int2_cmp(Datum a, Datum b, SortSupport ssup) +{ + int16KEY *ia = (int16KEY *) DatumGetPointer(a); + int16KEY *ib = (int16KEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_int2_abbrev_convert(Datum original, SortSupport ssup) +{ + int16KEY *b1 = (int16KEY *) DatumGetPointer(original); + int16 z = b1->lower; + + return (Datum) z; +} + +static int +gbt_int2_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_int2_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_int2_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_int2_cmp_abbrev; + ssup->abbrev_converter = gbt_int2_abbrev_convert; + ssup->abbrev_abort = gbt_int2_abbrev_abort; + ssup->abbrev_full_comparator = gbt_int2_cmp; + } + else + { + ssup->comparator = gbt_int2_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c index 7ea98c478c..327d771230 100644 --- a/contrib/btree_gist/btree_int4.c +++ b/contrib/btree_gist/btree_int4.c @@ -24,6 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_int4_consistent); PG_FUNCTION_INFO_V1(gbt_int4_distance); PG_FUNCTION_INFO_V1(gbt_int4_penalty); PG_FUNCTION_INFO_V1(gbt_int4_same); +PG_FUNCTION_INFO_V1(gbt_int4_sortsupport); static bool @@ -215,3 +216,72 @@ gbt_int4_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_int4_cmp(Datum a, Datum b, SortSupport ssup) +{ + int32KEY *ia = (int32KEY *) DatumGetPointer(a); + int32KEY *ib = (int32KEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_int4_abbrev_convert(Datum original, SortSupport ssup) +{ + int32KEY *b1 = (int32KEY *) DatumGetPointer(original); + int32 z = b1->lower; + + return (Datum) z; +} + +static int +gbt_int4_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_int4_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_int4_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_int4_cmp_abbrev; + ssup->abbrev_converter = gbt_int4_abbrev_convert; + ssup->abbrev_abort = gbt_int4_abbrev_abort; + ssup->abbrev_full_comparator = gbt_int4_cmp; + } + else + { + ssup->comparator = gbt_int4_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c index df2b0d174b..32f8c3b8b4 100644 --- a/contrib/btree_gist/btree_int8.c +++ b/contrib/btree_gist/btree_int8.c @@ -24,7 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_int8_consistent); PG_FUNCTION_INFO_V1(gbt_int8_distance); PG_FUNCTION_INFO_V1(gbt_int8_penalty); PG_FUNCTION_INFO_V1(gbt_int8_same); - +PG_FUNCTION_INFO_V1(gbt_int8_sortsupport); static bool gbt_int8gt(const void *a, const void *b, FmgrInfo *flinfo) @@ -215,3 +215,76 @@ gbt_int8_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_int8_cmp(Datum a, Datum b, SortSupport ssup) +{ + int64KEY *ia = (int64KEY *) DatumGetPointer(a); + int64KEY *ib = (int64KEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_int8_abbrev_convert(Datum original, SortSupport ssup) +{ + int64KEY *b1 = (int64KEY *) DatumGetPointer(original); + int64 z = b1->lower; + +#if SIZEOF_DATUM == 8 + return (Datum) z; +#else + return (Datum) (z >> 32); +#endif +} + +static int +gbt_int8_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_int8_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_int8_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_int8_cmp_abbrev; + ssup->abbrev_converter = gbt_int8_abbrev_convert; + ssup->abbrev_abort = gbt_int8_abbrev_abort; + ssup->abbrev_full_comparator = gbt_int8_cmp; + } + else + { + ssup->comparator = gbt_int8_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c index 7f0e9e9c91..d91369e260 100644 --- a/contrib/btree_gist/btree_macaddr.c +++ b/contrib/btree_gist/btree_macaddr.c @@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_macad_picksplit); PG_FUNCTION_INFO_V1(gbt_macad_consistent); PG_FUNCTION_INFO_V1(gbt_macad_penalty); PG_FUNCTION_INFO_V1(gbt_macad_same); +PG_FUNCTION_INFO_V1(gbt_macad_sortsupport); static bool @@ -195,3 +196,44 @@ gbt_macad_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_macad_cmp(Datum a, Datum b, SortSupport ssup) +{ + macKEY *ma = (macKEY *) DatumGetPointer(a); + macKEY *mb = (macKEY *) DatumGetPointer(b); + uint64 ia = mac_2_uint64(&ma->lower); + uint64 ib = mac_2_uint64(&mb->lower); + + /* for leaf items we expect lower == upper */ + + if (ia == ib) + { + return 0; + } + + return (ia > ib) ? 1 : -1; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_macad_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_macad_cmp; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_macad_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_macaddr8.c b/contrib/btree_gist/btree_macaddr8.c index ab4bca5d50..604871d789 100644 --- a/contrib/btree_gist/btree_macaddr8.c +++ b/contrib/btree_gist/btree_macaddr8.c @@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_macad8_picksplit); PG_FUNCTION_INFO_V1(gbt_macad8_consistent); PG_FUNCTION_INFO_V1(gbt_macad8_penalty); PG_FUNCTION_INFO_V1(gbt_macad8_same); +PG_FUNCTION_INFO_V1(gbt_macad8_sortsupport); static bool @@ -195,3 +196,43 @@ gbt_macad8_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_macad8_cmp(Datum a, Datum b, SortSupport ssup) +{ + mac8KEY *ma = (mac8KEY *) DatumGetPointer(a); + mac8KEY *mb = (mac8KEY *) DatumGetPointer(b); + uint64 ia = mac8_2_uint64(&ma->lower); + uint64 ib = mac8_2_uint64(&mb->lower); + + /* for leaf items we expect lower == upper */ + + if (ia == ib) + { + return 0; + } + + return (ia > ib) ? 1 : -1; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_macad8_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_macad8_cmp; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_macad8_cmp; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c index 35e466cdd9..f1f33793c5 100644 --- a/contrib/btree_gist/btree_numeric.c +++ b/contrib/btree_gist/btree_numeric.c @@ -21,6 +21,7 @@ PG_FUNCTION_INFO_V1(gbt_numeric_picksplit); PG_FUNCTION_INFO_V1(gbt_numeric_consistent); PG_FUNCTION_INFO_V1(gbt_numeric_penalty); PG_FUNCTION_INFO_V1(gbt_numeric_same); +PG_FUNCTION_INFO_V1(gbt_numeric_sortsupport); /* define for comparison */ @@ -227,3 +228,33 @@ gbt_numeric_picksplit(PG_FUNCTION_ARGS) &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(v); } + +static int +gbt_numeric_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + return DatumGetInt32(DirectFunctionCall2(numeric_cmp, + PointerGetDatum(a), + PointerGetDatum(b))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_numeric_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_numeric_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_numeric_cmp_sort; + } + PG_RETURN_VOID(); +} diff --git a/contrib/btree_gist/btree_oid.c b/contrib/btree_gist/btree_oid.c index 3cc7d4245d..5dcfc2ec48 100644 --- a/contrib/btree_gist/btree_oid.c +++ b/contrib/btree_gist/btree_oid.c @@ -23,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_oid_consistent); PG_FUNCTION_INFO_V1(gbt_oid_distance); PG_FUNCTION_INFO_V1(gbt_oid_penalty); PG_FUNCTION_INFO_V1(gbt_oid_same); +PG_FUNCTION_INFO_V1(gbt_oid_sortsupport); static bool @@ -215,3 +216,73 @@ gbt_oid_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_oid_cmp(Datum a, Datum b, SortSupport ssup) +{ + oidKEY *ia = (oidKEY *) DatumGetPointer(a); + oidKEY *ib = (oidKEY *) DatumGetPointer(b); + + /* for leaf items we expect lower == upper */ + Assert(ia->lower == ia->upper); + Assert(ib->lower == ib->upper); + + if (ia->lower == ib->lower) + { + return 0; + } + + return (ia->lower > ib->lower) ? 1 : -1; +} + +static Datum +gbt_oid_abbrev_convert(Datum original, SortSupport ssup) +{ + oidKEY *b1 = (oidKEY *) DatumGetPointer(original); + Oid z = b1->lower; + + return (Datum) z; +} + +static int +gbt_oid_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + */ +static bool +gbt_oid_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_oid_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_oid_cmp_abbrev; + ssup->abbrev_converter = gbt_oid_abbrev_convert; + ssup->abbrev_abort = gbt_oid_abbrev_abort; + ssup->abbrev_full_comparator = gbt_oid_cmp; + } + else + { + ssup->comparator = gbt_oid_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c index 8019d11281..78ecf4e18e 100644 --- a/contrib/btree_gist/btree_text.c +++ b/contrib/btree_gist/btree_text.c @@ -18,6 +18,7 @@ PG_FUNCTION_INFO_V1(gbt_text_consistent); PG_FUNCTION_INFO_V1(gbt_bpchar_consistent); PG_FUNCTION_INFO_V1(gbt_text_penalty); PG_FUNCTION_INFO_V1(gbt_text_same); +PG_FUNCTION_INFO_V1(gbt_text_sortsupport); /* define for comparison */ @@ -239,3 +240,35 @@ gbt_text_penalty(PG_FUNCTION_ARGS) PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo)); } + +static int +gbt_text_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp, + ssup->ssup_collation, + PointerGetDatum(a), + PointerGetDatum(b))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_text_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_text_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_text_cmp_sort; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c index fd8774a2f0..6198a6e104 100644 --- a/contrib/btree_gist/btree_time.c +++ b/contrib/btree_gist/btree_time.c @@ -28,6 +28,7 @@ PG_FUNCTION_INFO_V1(gbt_time_distance); PG_FUNCTION_INFO_V1(gbt_timetz_consistent); PG_FUNCTION_INFO_V1(gbt_time_penalty); PG_FUNCTION_INFO_V1(gbt_time_same); +PG_FUNCTION_INFO_V1(gbt_time_sortsupport); #ifdef USE_FLOAT8_BYVAL @@ -332,3 +333,36 @@ gbt_time_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_time_cmp_sort(Datum a, Datum b, SortSupport ssup) +{ + timeKEY *ia = (timeKEY *) DatumGetPointer(a); + timeKEY *ib = (timeKEY *) DatumGetPointer(b); + + return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_time_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_time_cmp_sort; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_time_cmp_sort; + } + PG_RETURN_VOID(); +} + + diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c index 2671ba961c..6e699ed198 100644 --- a/contrib/btree_gist/btree_ts.c +++ b/contrib/btree_gist/btree_ts.c @@ -31,6 +31,7 @@ PG_FUNCTION_INFO_V1(gbt_tstz_consistent); PG_FUNCTION_INFO_V1(gbt_tstz_distance); PG_FUNCTION_INFO_V1(gbt_ts_penalty); PG_FUNCTION_INFO_V1(gbt_ts_same); +PG_FUNCTION_INFO_V1(gbt_ts_sortsupport); #ifdef USE_FLOAT8_BYVAL @@ -399,3 +400,35 @@ gbt_ts_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_ts_cmp(Datum a, Datum b, SortSupport ssup) +{ + tsKEY *ia = (tsKEY *) DatumGetPointer(a); + tsKEY *ib = (tsKEY *) DatumGetPointer(b); + + return DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatumFast(ia->lower), TimestampGetDatumFast(ib->lower))); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_ts_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_ts_cmp; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_ts_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/contrib/btree_gist/btree_uuid.c b/contrib/btree_gist/btree_uuid.c index b81875979a..e99432bceb 100644 --- a/contrib/btree_gist/btree_uuid.c +++ b/contrib/btree_gist/btree_uuid.c @@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_uuid_picksplit); PG_FUNCTION_INFO_V1(gbt_uuid_consistent); PG_FUNCTION_INFO_V1(gbt_uuid_penalty); PG_FUNCTION_INFO_V1(gbt_uuid_same); +PG_FUNCTION_INFO_V1(gbt_uuid_sortsupport); static int @@ -233,3 +234,35 @@ gbt_uuid_same(PG_FUNCTION_ARGS) *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo); PG_RETURN_POINTER(result); } + +static int +gbt_uuid_cmp(Datum a, Datum b, SortSupport ssup) +{ + uuidKEY *ua = (uuidKEY *) DatumGetPointer(a); + uuidKEY *ub = (uuidKEY *) DatumGetPointer(b); + + return uuid_internal_cmp(&ua->lower, &ub->lower); +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gbt_uuid_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gbt_uuid_cmp; + ssup->abbrev_converter = NULL; + ssup->abbrev_abort = NULL; + ssup->abbrev_full_comparator = NULL; + } + else + { + ssup->comparator = gbt_uuid_cmp; + } + PG_RETURN_VOID(); +} + diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c index 8a14620fab..e600015b12 100644 --- a/src/backend/access/gist/gistvalidate.c +++ b/src/backend/access/gist/gistvalidate.c @@ -338,6 +338,7 @@ gistadjustmembers(Oid opfamilyoid, case GIST_DISTANCE_PROC: case GIST_FETCH_PROC: case GIST_OPTIONS_PROC: + case GIST_SORTSUPPORT_PROC: /* Optional, so force it to be a soft family dependency */ op->ref_is_hard = false; op->ref_is_family = true; -- 2.24.3 (Apple Git-128)