Skip to content

Commit 9f984ba

Browse files
committed
Add sortsupport for gist_btree opclasses, for faster index builds.
Commit 16fa9b2 introduced a faster way to build GiST indexes, by sorting all the data. This commit adds the sortsupport functions needed to make use of that feature for btree_gist. Author: Andrey Borodin Discussion: https://www.postgresql.org/message-id/[email protected]
1 parent dd13ad9 commit 9f984ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1530
-3
lines changed

contrib/btree_gist/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ EXTENSION = btree_gist
3232
DATA = btree_gist--1.0--1.1.sql \
3333
btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql \
3434
btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.sql \
35-
btree_gist--1.5--1.6.sql
35+
btree_gist--1.5--1.6.sql btree_gist--1.6--1.7.sql
3636
PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
3737

3838
REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \

contrib/btree_gist/btree_bit.c

+25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
1919
PG_FUNCTION_INFO_V1(gbt_bit_consistent);
2020
PG_FUNCTION_INFO_V1(gbt_bit_penalty);
2121
PG_FUNCTION_INFO_V1(gbt_bit_same);
22+
PG_FUNCTION_INFO_V1(gbt_bit_sortsupport);
2223

2324

2425
/* define for comparison */
@@ -209,3 +210,27 @@ gbt_bit_penalty(PG_FUNCTION_ARGS)
209210
PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
210211
&tinfo, fcinfo->flinfo));
211212
}
213+
214+
static int
215+
gbt_bit_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
216+
{
217+
/* Use byteacmp(), like gbt_bitcmp() does */
218+
return DatumGetInt32(DirectFunctionCall2(byteacmp,
219+
PointerGetDatum(a),
220+
PointerGetDatum(b)));
221+
}
222+
223+
/*
224+
* Sort support routine for fast GiST index build by sorting.
225+
*/
226+
Datum
227+
gbt_bit_sortsupport(PG_FUNCTION_ARGS)
228+
{
229+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
230+
231+
ssup->comparator = gbt_bit_sort_build_cmp;
232+
ssup->abbrev_converter = NULL;
233+
ssup->abbrev_abort = NULL;
234+
ssup->abbrev_full_comparator = NULL;
235+
PG_RETURN_VOID();
236+
}

contrib/btree_gist/btree_bytea.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
1818
PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
1919
PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
2020
PG_FUNCTION_INFO_V1(gbt_bytea_same);
21+
PG_FUNCTION_INFO_V1(gbt_bytea_sortsupport);
2122

2223

2324
/* define for comparison */
@@ -87,7 +88,7 @@ static const gbtree_vinfo tinfo =
8788

8889

8990
/**************************************************
90-
* Text ops
91+
* Bytea ops
9192
**************************************************/
9293

9394

@@ -168,3 +169,26 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS)
168169
PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
169170
&tinfo, fcinfo->flinfo));
170171
}
172+
173+
static int
174+
gbt_bytea_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
175+
{
176+
return DatumGetInt32(DirectFunctionCall2(byteacmp,
177+
PointerGetDatum(a),
178+
PointerGetDatum(b)));
179+
}
180+
181+
/*
182+
* Sort support routine for fast GiST index build by sorting.
183+
*/
184+
Datum
185+
gbt_bytea_sortsupport(PG_FUNCTION_ARGS)
186+
{
187+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
188+
189+
ssup->comparator = gbt_bytea_sort_build_cmp;
190+
ssup->abbrev_converter = NULL;
191+
ssup->abbrev_abort = NULL;
192+
ssup->abbrev_full_comparator = NULL;
193+
PG_RETURN_VOID();
194+
}

contrib/btree_gist/btree_cash.c

+80
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_cash_consistent);
2525
PG_FUNCTION_INFO_V1(gbt_cash_distance);
2626
PG_FUNCTION_INFO_V1(gbt_cash_penalty);
2727
PG_FUNCTION_INFO_V1(gbt_cash_same);
28+
PG_FUNCTION_INFO_V1(gbt_cash_sortsupport);
2829

2930
static bool
3031
gbt_cashgt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -216,3 +217,82 @@ gbt_cash_same(PG_FUNCTION_ARGS)
216217
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
217218
PG_RETURN_POINTER(result);
218219
}
220+
221+
static int
222+
gbt_cash_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
223+
{
224+
cashKEY *ia = (cashKEY *) DatumGetPointer(a);
225+
cashKEY *ib = (cashKEY *) DatumGetPointer(b);
226+
227+
/* for leaf items we expect lower == upper */
228+
Assert(ia->lower == ia->upper);
229+
Assert(ib->lower == ib->upper);
230+
231+
if (ia->lower == ib->lower)
232+
return 0;
233+
234+
return (ia->lower > ib->lower) ? 1 : -1;
235+
}
236+
237+
static Datum
238+
gbt_cash_abbrev_convert(Datum original, SortSupport ssup)
239+
{
240+
cashKEY *b1 = (cashKEY *) DatumGetPointer(original);
241+
int64 z = b1->lower;
242+
243+
#if SIZEOF_DATUM == 8
244+
return Int64GetDatum(z);
245+
#else
246+
return Int32GetDatum(z >> 32);
247+
#endif
248+
}
249+
250+
static int
251+
gbt_cash_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup)
252+
{
253+
#if SIZEOF_DATUM == 8
254+
int64 a = DatumGetInt64(z1);
255+
int64 b = DatumGetInt64(z2);
256+
#else
257+
int32 a = DatumGetInt32(z1);
258+
int32 b = DatumGetInt32(z2);
259+
#endif
260+
261+
if (a > b)
262+
return 1;
263+
else if (a < b)
264+
return -1;
265+
else
266+
return 0;
267+
}
268+
269+
/*
270+
* We never consider aborting the abbreviation.
271+
*/
272+
static bool
273+
gbt_cash_abbrev_abort(int memtupcount, SortSupport ssup)
274+
{
275+
return false;
276+
}
277+
278+
/*
279+
* Sort support routine for fast GiST index build by sorting.
280+
*/
281+
Datum
282+
gbt_cash_sortsupport(PG_FUNCTION_ARGS)
283+
{
284+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
285+
286+
if (ssup->abbreviate)
287+
{
288+
ssup->comparator = gbt_cash_cmp_abbrev;
289+
ssup->abbrev_converter = gbt_cash_abbrev_convert;
290+
ssup->abbrev_abort = gbt_cash_abbrev_abort;
291+
ssup->abbrev_full_comparator = gbt_cash_sort_build_cmp;
292+
}
293+
else
294+
{
295+
ssup->comparator = gbt_cash_sort_build_cmp;
296+
}
297+
PG_RETURN_VOID();
298+
}

contrib/btree_gist/btree_date.c

+27
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ PG_FUNCTION_INFO_V1(gbt_date_consistent);
2525
PG_FUNCTION_INFO_V1(gbt_date_distance);
2626
PG_FUNCTION_INFO_V1(gbt_date_penalty);
2727
PG_FUNCTION_INFO_V1(gbt_date_same);
28+
PG_FUNCTION_INFO_V1(gbt_date_sortsupport);
2829

2930
static bool
3031
gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -257,3 +258,29 @@ gbt_date_same(PG_FUNCTION_ARGS)
257258
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
258259
PG_RETURN_POINTER(result);
259260
}
261+
262+
static int
263+
gbt_date_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
264+
{
265+
dateKEY *ia = (dateKEY *) PointerGetDatum(a);
266+
dateKEY *ib = (dateKEY *) PointerGetDatum(b);
267+
268+
return DatumGetInt32(DirectFunctionCall2(date_cmp,
269+
DateADTGetDatum(ia->lower),
270+
DateADTGetDatum(ib->lower)));
271+
}
272+
273+
/*
274+
* Sort support routine for fast GiST index build by sorting.
275+
*/
276+
Datum
277+
gbt_date_sortsupport(PG_FUNCTION_ARGS)
278+
{
279+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
280+
281+
ssup->comparator = gbt_date_sort_build_cmp;
282+
ssup->abbrev_converter = NULL;
283+
ssup->abbrev_abort = NULL;
284+
ssup->abbrev_full_comparator = NULL;
285+
PG_RETURN_VOID();
286+
}

contrib/btree_gist/btree_enum.c

+70
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
2626
PG_FUNCTION_INFO_V1(gbt_enum_consistent);
2727
PG_FUNCTION_INFO_V1(gbt_enum_penalty);
2828
PG_FUNCTION_INFO_V1(gbt_enum_same);
29+
PG_FUNCTION_INFO_V1(gbt_enum_sortsupport);
2930

3031

3132
static bool
@@ -183,3 +184,72 @@ gbt_enum_same(PG_FUNCTION_ARGS)
183184
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
184185
PG_RETURN_POINTER(result);
185186
}
187+
188+
static int
189+
gbt_enum_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
190+
{
191+
oidKEY *ia = (oidKEY *) DatumGetPointer(a);
192+
oidKEY *ib = (oidKEY *) DatumGetPointer(b);
193+
194+
/* for leaf items we expect lower == upper */
195+
Assert(ia->lower == ia->upper);
196+
Assert(ib->lower == ib->upper);
197+
198+
if (ia->lower == ib->lower)
199+
return 0;
200+
201+
return (ia->lower > ib->lower) ? 1 : -1;
202+
}
203+
204+
static Datum
205+
gbt_enum_abbrev_convert(Datum original, SortSupport ssup)
206+
{
207+
oidKEY *b1 = (oidKEY *) DatumGetPointer(original);
208+
209+
return ObjectIdGetDatum(b1->lower);
210+
}
211+
212+
static int
213+
gbt_enum_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup)
214+
{
215+
Oid a = DatumGetObjectId(z1);
216+
Oid b = DatumGetObjectId(z2);
217+
218+
if (a > b)
219+
return 1;
220+
else if (a < b)
221+
return -1;
222+
else
223+
return 0;
224+
}
225+
226+
/*
227+
* We never consider aborting the abbreviation.
228+
*/
229+
static bool
230+
gbt_enum_abbrev_abort(int memtupcount, SortSupport ssup)
231+
{
232+
return false;
233+
}
234+
235+
/*
236+
* Sort support routine for fast GiST index build by sorting.
237+
*/
238+
Datum
239+
gbt_enum_sortsupport(PG_FUNCTION_ARGS)
240+
{
241+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
242+
243+
if (ssup->abbreviate)
244+
{
245+
ssup->comparator = gbt_enum_cmp_abbrev;
246+
ssup->abbrev_converter = gbt_enum_abbrev_convert;
247+
ssup->abbrev_abort = gbt_enum_abbrev_abort;
248+
ssup->abbrev_full_comparator = gbt_enum_sort_build_cmp;
249+
}
250+
else
251+
{
252+
ssup->comparator = gbt_enum_sort_build_cmp;
253+
}
254+
PG_RETURN_VOID();
255+
}

contrib/btree_gist/btree_float4.c

+71
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_float4_consistent);
2323
PG_FUNCTION_INFO_V1(gbt_float4_distance);
2424
PG_FUNCTION_INFO_V1(gbt_float4_penalty);
2525
PG_FUNCTION_INFO_V1(gbt_float4_same);
26+
PG_FUNCTION_INFO_V1(gbt_float4_sortsupport);
2627

2728
static bool
2829
gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -209,3 +210,73 @@ gbt_float4_same(PG_FUNCTION_ARGS)
209210
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
210211
PG_RETURN_POINTER(result);
211212
}
213+
214+
215+
static int
216+
gbt_float4_sort_build_cmp(Datum a, Datum b, SortSupport ssup)
217+
{
218+
float4KEY *ia = (float4KEY *) DatumGetPointer(a);
219+
float4KEY *ib = (float4KEY *) DatumGetPointer(b);
220+
221+
/* for leaf items we expect lower == upper */
222+
Assert(ia->lower == ia->upper);
223+
Assert(ib->lower == ib->upper);
224+
225+
if (ia->lower == ib->lower)
226+
return 0;
227+
228+
return (ia->lower > ib->lower) ? 1 : -1;
229+
}
230+
231+
static Datum
232+
gbt_float4_abbrev_convert(Datum original, SortSupport ssup)
233+
{
234+
float4KEY *b1 = (float4KEY *) DatumGetPointer(original);
235+
236+
return Float4GetDatum(b1->lower);
237+
}
238+
239+
static int
240+
gbt_float4_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup)
241+
{
242+
float4 a = DatumGetFloat4(z1);
243+
float4 b = DatumGetFloat4(z2);
244+
245+
if (a > b)
246+
return 1;
247+
else if (a < b)
248+
return -1;
249+
else
250+
return 0;
251+
}
252+
253+
/*
254+
* We never consider aborting the abbreviation.
255+
*/
256+
static bool
257+
gbt_float4_abbrev_abort(int memtupcount, SortSupport ssup)
258+
{
259+
return false;
260+
}
261+
262+
/*
263+
* Sort support routine for fast GiST index build by sorting.
264+
*/
265+
Datum
266+
gbt_float4_sortsupport(PG_FUNCTION_ARGS)
267+
{
268+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
269+
270+
if (ssup->abbreviate)
271+
{
272+
ssup->comparator = gbt_float4_cmp_abbrev;
273+
ssup->abbrev_converter = gbt_float4_abbrev_convert;
274+
ssup->abbrev_abort = gbt_float4_abbrev_abort;
275+
ssup->abbrev_full_comparator = gbt_float4_sort_build_cmp;
276+
}
277+
else
278+
{
279+
ssup->comparator = gbt_float4_sort_build_cmp;
280+
}
281+
PG_RETURN_VOID();
282+
}

0 commit comments

Comments
 (0)