Re: [PATCH] Add sortsupport for range types and btree_gist - Mailing list pgsql-hackers
From | jian he |
---|---|
Subject | Re: [PATCH] Add sortsupport for range types and btree_gist |
Date | |
Msg-id | CACJufxEVYNCQJEnRr6jpdrNSb9hH6YkavxrLabrRuCWoeTDHjQ@mail.gmail.com Whole thread Raw |
In response to | Re: [PATCH] Add sortsupport for range types and btree_gist (jian he <jian.universality@gmail.com>) |
Responses |
Re: [PATCH] Add sortsupport for range types and btree_gist
Re: [PATCH] Add sortsupport for range types and btree_gist Re: [PATCH] Add sortsupport for range types and btree_gist |
List | pgsql-hackers |
On Wed, Jan 10, 2024 at 8:00 AM jian he <jian.universality@gmail.com> wrote: > > ` > from the doc, add sortsupport function will only influence index build time? > > +/* > + * GiST sortsupport comparator for ranges. > + * > + * Operates solely on the lower bounds of the ranges, comparing them using > + * range_cmp_bounds(). > + * Empty ranges are sorted before non-empty ones. > + */ > +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); > + > + /* For b-tree use, empty ranges sort before all else */ > + if (empty1 && empty2) > + result = 0; > + else if (empty1) > + result = -1; > + else if (empty2) > + result = 1; > + else > + result = range_cmp_bounds(typcache, &lower1, &lower2); > + > + if ((Datum) range_a != a) > + pfree(range_a); > + > + if ((Datum) range_b != b) > + pfree(range_b); > + > + return result; > +} > > per https://www.postgresql.org/docs/current/gist-extensibility.html > QUOTE: > All the GiST support methods are normally called in short-lived memory > contexts; that is, CurrentMemoryContext will get reset after each > tuple is processed. It is therefore not very important to worry about > pfree'ing everything you palloc. However, in some cases it's useful > for a support method to > ENDOF_QUOTE > > so removing the following part should be OK. > + if ((Datum) range_a != a) > + pfree(range_a); > + > + if ((Datum) range_b != b) > + pfree(range_b); > > comparison solely on the lower bounds looks strange to me. > if lower bound is the same, then compare upper bound, so the > range_gist_cmp function is consistent with function range_compare. > so following change: > > + else > + result = range_cmp_bounds(typcache, &lower1, &lower2); > to > ` > else > { > result = range_cmp_bounds(typcache, &lower1, &lower2); > if (result == 0) > result = range_cmp_bounds(typcache, &upper1, &upper2); > } > ` > > does contrib/btree_gist/btree_gist--1.7--1.8.sql function be declared > as strict ? (I am not sure) > other than that, the whole patch looks good. the original author email address (christoph.heiss@cybertec.at) Address not found. so I don't include it. I split the original author's patch into 2. 1. Add GiST sortsupport function for all the btree-gist module data types except anyrange data type (which actually does not in this module) 2. Add GiST sortsupport function for anyrange data type. What changed compared to the original patch: 1. The original patch missed some operator class for all the data types in btree-gist modules. So I added them. now add sortsupport function for all the following data types in btree-gist: int2,int4,int8,float4,float8,numeric timestamp with time zone, timestamp without time zone, time with time zone, time without time zone, date interval, oid, money, char varchar, text, bytea, bit, varbit macaddr, macaddr8, inet, cidr, uuid, bool, enum 2. range_gist_cmp: the gist range sortsupport function, it looks like range_cmp, but the range typcache is cached, so we don't need to repeatedly call lookup_type_cache. refactor: As mentioned above, if the range lower bound is the same then compare the upper bound. I aslo refactored the comment. what I am confused: In fmgr.h /* * Support for cleaning up detoasted copies of inputs. This must only * be used for pass-by-ref datatypes, and normally would only be used * for toastable types. If the given pointer is different from the * original argument, assume it's a palloc'd detoasted copy, and pfree it. * NOTE: most functions on toastable types do not have to worry about this, * but we currently require that support functions for indexes not leak * memory. */ #define PG_FREE_IF_COPY(ptr,n) \ do { \ if ((Pointer) (ptr) != PG_GETARG_POINTER(n)) \ pfree(ptr); \ } while (0) but the doc (https://www.postgresql.org/docs/current/gist-extensibility.html) says: All the GiST support methods are normally called in short-lived memory contexts; that is, CurrentMemoryContext will get reset after each tuple is processed. It is therefore not very important to worry about pfree'ing everything you palloc. ENDOF_QUOTE so I am not sure in range_gist_cmp, we need the following: ` if ((Datum) range_a != a) pfree(range_a); if ((Datum) range_b != b) pfree(range_b); `
Attachment
pgsql-hackers by date: