Skip to content

Commit e4309f7

Browse files
committed
Add support for sorted gist index builds to btree_gist
This enables sortsupport in the btree_gist extension for faster builds of gist indexes. Sorted gist index build strategy is the new default now. Regression tests are unchanged (except for one small change in the 'enum' test to add coverage for enum values added later) and are using the sorted build strategy instead. One version of this was committed a long time ago already, in commit 9f984ba, but it was quickly reverted because of buildfarm failures. The failures were presumably caused by some small bugs, but we never got around to debug and commit it again. This patch was written from scratch, implementing the same idea, with some fragments and ideas from the original patch. Author: Bernd Helmle <mailings@oopsware.de> Author: Andrey Borodin <x4mmm@yandex-team.ru> Discussion: https://www.postgresql.org/message-id/64d324ce2a6d535d3f0f3baeeea7b25beff82ce4.camel@oopsware.de
1 parent 9370978 commit e4309f7

29 files changed

+855
-6
lines changed

contrib/btree_gist/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ DATA = btree_gist--1.0--1.1.sql \
3434
btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql \
3535
btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.sql \
3636
btree_gist--1.5--1.6.sql btree_gist--1.6--1.7.sql \
37-
btree_gist--1.7--1.8.sql
37+
btree_gist--1.7--1.8.sql btree_gist--1.8--1.9.sql
3838
PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
3939

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

contrib/btree_gist/btree_bit.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "btree_gist.h"
77
#include "btree_utils_var.h"
88
#include "utils/fmgrprotos.h"
9+
#include "utils/sortsupport.h"
910
#include "utils/varbit.h"
1011

1112
/* GiST support functions */
@@ -15,6 +16,8 @@ PG_FUNCTION_INFO_V1(gbt_bit_picksplit);
1516
PG_FUNCTION_INFO_V1(gbt_bit_consistent);
1617
PG_FUNCTION_INFO_V1(gbt_bit_penalty);
1718
PG_FUNCTION_INFO_V1(gbt_bit_same);
19+
PG_FUNCTION_INFO_V1(gbt_bit_sortsupport);
20+
PG_FUNCTION_INFO_V1(gbt_varbit_sortsupport);
1821

1922

2023
/* define for comparison */
@@ -200,3 +203,46 @@ gbt_bit_penalty(PG_FUNCTION_ARGS)
200203
PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
201204
&tinfo, fcinfo->flinfo));
202205
}
206+
207+
static int
208+
gbt_bit_ssup_cmp(Datum x, Datum y, SortSupport ssup)
209+
{
210+
GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
211+
GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
212+
213+
GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
214+
GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
215+
Datum result;
216+
217+
/* for leaf items we expect lower == upper, so only compare lower */
218+
result = DirectFunctionCall2(byteacmp,
219+
PointerGetDatum(arg1.lower),
220+
PointerGetDatum(arg2.lower));
221+
222+
GBT_FREE_IF_COPY(key1, x);
223+
GBT_FREE_IF_COPY(key2, y);
224+
225+
return DatumGetInt32(result);
226+
}
227+
228+
Datum
229+
gbt_bit_sortsupport(PG_FUNCTION_ARGS)
230+
{
231+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
232+
233+
ssup->comparator = gbt_bit_ssup_cmp;
234+
ssup->ssup_extra = NULL;
235+
236+
PG_RETURN_VOID();
237+
}
238+
239+
Datum
240+
gbt_varbit_sortsupport(PG_FUNCTION_ARGS)
241+
{
242+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
243+
244+
ssup->comparator = gbt_bit_ssup_cmp;
245+
ssup->ssup_extra = NULL;
246+
247+
PG_RETURN_VOID();
248+
}

contrib/btree_gist/btree_bool.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "btree_gist.h"
77
#include "btree_utils_num.h"
8+
#include "utils/sortsupport.h"
89

910
typedef struct boolkey
1011
{
@@ -20,6 +21,7 @@ PG_FUNCTION_INFO_V1(gbt_bool_picksplit);
2021
PG_FUNCTION_INFO_V1(gbt_bool_consistent);
2122
PG_FUNCTION_INFO_V1(gbt_bool_penalty);
2223
PG_FUNCTION_INFO_V1(gbt_bool_same);
24+
PG_FUNCTION_INFO_V1(gbt_bool_sortsupport);
2325

2426
static bool
2527
gbt_boolgt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -161,3 +163,24 @@ gbt_bool_same(PG_FUNCTION_ARGS)
161163
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
162164
PG_RETURN_POINTER(result);
163165
}
166+
167+
static int
168+
gbt_bool_ssup_cmp(Datum x, Datum y, SortSupport ssup)
169+
{
170+
boolKEY *arg1 = (boolKEY *) DatumGetPointer(x);
171+
boolKEY *arg2 = (boolKEY *) DatumGetPointer(y);
172+
173+
/* for leaf items we expect lower == upper, so only compare lower */
174+
return (int32) arg1->lower - (int32) arg2->lower;
175+
}
176+
177+
Datum
178+
gbt_bool_sortsupport(PG_FUNCTION_ARGS)
179+
{
180+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
181+
182+
ssup->comparator = gbt_bool_ssup_cmp;
183+
ssup->ssup_extra = NULL;
184+
185+
PG_RETURN_VOID();
186+
}

contrib/btree_gist/btree_bytea.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "btree_gist.h"
77
#include "btree_utils_var.h"
88
#include "utils/fmgrprotos.h"
9+
#include "utils/sortsupport.h"
910

1011
/* GiST support functions */
1112
PG_FUNCTION_INFO_V1(gbt_bytea_compress);
@@ -14,6 +15,7 @@ PG_FUNCTION_INFO_V1(gbt_bytea_picksplit);
1415
PG_FUNCTION_INFO_V1(gbt_bytea_consistent);
1516
PG_FUNCTION_INFO_V1(gbt_bytea_penalty);
1617
PG_FUNCTION_INFO_V1(gbt_bytea_same);
18+
PG_FUNCTION_INFO_V1(gbt_bytea_sortsupport);
1719

1820

1921
/* define for comparison */
@@ -156,3 +158,35 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS)
156158
PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
157159
&tinfo, fcinfo->flinfo));
158160
}
161+
162+
static int
163+
gbt_bytea_ssup_cmp(Datum x, Datum y, SortSupport ssup)
164+
{
165+
GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
166+
GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
167+
168+
GBT_VARKEY_R xkey = gbt_var_key_readable(key1);
169+
GBT_VARKEY_R ykey = gbt_var_key_readable(key2);
170+
Datum result;
171+
172+
/* for leaf items we expect lower == upper, so only compare lower */
173+
result = DirectFunctionCall2(byteacmp,
174+
PointerGetDatum(xkey.lower),
175+
PointerGetDatum(ykey.lower));
176+
177+
GBT_FREE_IF_COPY(key1, x);
178+
GBT_FREE_IF_COPY(key2, y);
179+
180+
return DatumGetInt32(result);
181+
}
182+
183+
Datum
184+
gbt_bytea_sortsupport(PG_FUNCTION_ARGS)
185+
{
186+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
187+
188+
ssup->comparator = gbt_bytea_ssup_cmp;
189+
ssup->ssup_extra = NULL;
190+
191+
PG_RETURN_VOID();
192+
}

contrib/btree_gist/btree_cash.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "btree_utils_num.h"
88
#include "common/int.h"
99
#include "utils/cash.h"
10+
#include "utils/sortsupport.h"
1011

1112
typedef struct
1213
{
@@ -23,6 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_cash_consistent);
2324
PG_FUNCTION_INFO_V1(gbt_cash_distance);
2425
PG_FUNCTION_INFO_V1(gbt_cash_penalty);
2526
PG_FUNCTION_INFO_V1(gbt_cash_same);
27+
PG_FUNCTION_INFO_V1(gbt_cash_sortsupport);
2628

2729
static bool
2830
gbt_cashgt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -210,3 +212,29 @@ gbt_cash_same(PG_FUNCTION_ARGS)
210212
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
211213
PG_RETURN_POINTER(result);
212214
}
215+
216+
static int
217+
gbt_cash_ssup_cmp(Datum x, Datum y, SortSupport ssup)
218+
{
219+
cashKEY *arg1 = (cashKEY *) DatumGetPointer(x);
220+
cashKEY *arg2 = (cashKEY *) DatumGetPointer(y);
221+
222+
/* for leaf items we expect lower == upper, so only compare lower */
223+
if (arg1->lower > arg2->lower)
224+
return 1;
225+
else if (arg1->lower < arg2->lower)
226+
return -1;
227+
else
228+
return 0;
229+
}
230+
231+
Datum
232+
gbt_cash_sortsupport(PG_FUNCTION_ARGS)
233+
{
234+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
235+
236+
ssup->comparator = gbt_cash_ssup_cmp;
237+
ssup->ssup_extra = NULL;
238+
239+
PG_RETURN_VOID();
240+
}

contrib/btree_gist/btree_date.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "btree_utils_num.h"
88
#include "utils/fmgrprotos.h"
99
#include "utils/date.h"
10+
#include "utils/sortsupport.h"
1011

1112
typedef struct
1213
{
@@ -23,6 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_date_consistent);
2324
PG_FUNCTION_INFO_V1(gbt_date_distance);
2425
PG_FUNCTION_INFO_V1(gbt_date_penalty);
2526
PG_FUNCTION_INFO_V1(gbt_date_same);
27+
PG_FUNCTION_INFO_V1(gbt_date_sortsupport);
2628

2729
static bool
2830
gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -249,3 +251,26 @@ gbt_date_same(PG_FUNCTION_ARGS)
249251
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
250252
PG_RETURN_POINTER(result);
251253
}
254+
255+
static int
256+
gbt_date_ssup_cmp(Datum x, Datum y, SortSupport ssup)
257+
{
258+
dateKEY *akey = (dateKEY *) DatumGetPointer(x);
259+
dateKEY *bkey = (dateKEY *) DatumGetPointer(y);
260+
261+
/* for leaf items we expect lower == upper, so only compare lower */
262+
return DatumGetInt32(DirectFunctionCall2(date_cmp,
263+
DateADTGetDatum(akey->lower),
264+
DateADTGetDatum(bkey->lower)));
265+
}
266+
267+
Datum
268+
gbt_date_sortsupport(PG_FUNCTION_ARGS)
269+
{
270+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
271+
272+
ssup->comparator = gbt_date_ssup_cmp;
273+
ssup->ssup_extra = NULL;
274+
275+
PG_RETURN_VOID();
276+
}

contrib/btree_gist/btree_enum.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "btree_utils_num.h"
88
#include "fmgr.h"
99
#include "utils/fmgrprotos.h"
10+
#include "utils/fmgroids.h"
11+
#include "utils/sortsupport.h"
1012

1113
/* enums are really Oids, so we just use the same structure */
1214

@@ -24,6 +26,7 @@ PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
2426
PG_FUNCTION_INFO_V1(gbt_enum_consistent);
2527
PG_FUNCTION_INFO_V1(gbt_enum_penalty);
2628
PG_FUNCTION_INFO_V1(gbt_enum_same);
29+
PG_FUNCTION_INFO_V1(gbt_enum_sortsupport);
2730

2831

2932
static bool
@@ -179,3 +182,39 @@ gbt_enum_same(PG_FUNCTION_ARGS)
179182
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
180183
PG_RETURN_POINTER(result);
181184
}
185+
186+
static int
187+
gbt_enum_ssup_cmp(Datum x, Datum y, SortSupport ssup)
188+
{
189+
oidKEY *arg1 = (oidKEY *) DatumGetPointer(x);
190+
oidKEY *arg2 = (oidKEY *) DatumGetPointer(y);
191+
192+
/* for leaf items we expect lower == upper, so only compare lower */
193+
return DatumGetInt32(CallerFInfoFunctionCall2(enum_cmp,
194+
ssup->ssup_extra,
195+
InvalidOid,
196+
arg1->lower,
197+
arg2->lower));
198+
}
199+
200+
Datum
201+
gbt_enum_sortsupport(PG_FUNCTION_ARGS)
202+
{
203+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
204+
FmgrInfo *flinfo;
205+
206+
ssup->comparator = gbt_enum_ssup_cmp;
207+
208+
/*
209+
* Since gbt_enum_ssup_cmp() uses enum_cmp() like the rest of the
210+
* comparison functions, it also needs to pass flinfo when calling it. The
211+
* caller to a SortSupport comparison function doesn't provide an FmgrInfo
212+
* struct, so look it up now, save it in ssup_extra and use it in
213+
* gbt_enum_ssup_cmp() later.
214+
*/
215+
flinfo = MemoryContextAlloc(ssup->ssup_cxt, sizeof(FmgrInfo));
216+
fmgr_info_cxt(F_ENUM_CMP, flinfo, ssup->ssup_cxt);
217+
ssup->ssup_extra = flinfo;
218+
219+
PG_RETURN_VOID();
220+
}

contrib/btree_gist/btree_float4.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "btree_gist.h"
77
#include "btree_utils_num.h"
88
#include "utils/float.h"
9+
#include "utils/sortsupport.h"
910

1011
typedef struct float4key
1112
{
@@ -22,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_float4_consistent);
2223
PG_FUNCTION_INFO_V1(gbt_float4_distance);
2324
PG_FUNCTION_INFO_V1(gbt_float4_penalty);
2425
PG_FUNCTION_INFO_V1(gbt_float4_same);
26+
PG_FUNCTION_INFO_V1(gbt_float4_sortsupport);
2527

2628
static bool
2729
gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo)
@@ -204,3 +206,24 @@ gbt_float4_same(PG_FUNCTION_ARGS)
204206
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
205207
PG_RETURN_POINTER(result);
206208
}
209+
210+
static int
211+
gbt_float4_ssup_cmp(Datum x, Datum y, SortSupport ssup)
212+
{
213+
float4KEY *arg1 = (float4KEY *) DatumGetPointer(x);
214+
float4KEY *arg2 = (float4KEY *) DatumGetPointer(y);
215+
216+
/* for leaf items we expect lower == upper, so only compare lower */
217+
return float4_cmp_internal(arg1->lower, arg2->lower);
218+
}
219+
220+
Datum
221+
gbt_float4_sortsupport(PG_FUNCTION_ARGS)
222+
{
223+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
224+
225+
ssup->comparator = gbt_float4_ssup_cmp;
226+
ssup->ssup_extra = NULL;
227+
228+
PG_RETURN_VOID();
229+
}

contrib/btree_gist/btree_float8.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "btree_gist.h"
77
#include "btree_utils_num.h"
88
#include "utils/float.h"
9+
#include "utils/sortsupport.h"
910

1011
typedef struct float8key
1112
{
@@ -22,6 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_float8_consistent);
2223
PG_FUNCTION_INFO_V1(gbt_float8_distance);
2324
PG_FUNCTION_INFO_V1(gbt_float8_penalty);
2425
PG_FUNCTION_INFO_V1(gbt_float8_same);
26+
PG_FUNCTION_INFO_V1(gbt_float8_sortsupport);
2527

2628

2729
static bool
@@ -212,3 +214,24 @@ gbt_float8_same(PG_FUNCTION_ARGS)
212214
*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
213215
PG_RETURN_POINTER(result);
214216
}
217+
218+
static int
219+
gbt_float8_ssup_cmp(Datum x, Datum y, SortSupport ssup)
220+
{
221+
float8KEY *arg1 = (float8KEY *) DatumGetPointer(x);
222+
float8KEY *arg2 = (float8KEY *) DatumGetPointer(y);
223+
224+
/* for leaf items we expect lower == upper, so only compare lower */
225+
return float8_cmp_internal(arg1->lower, arg2->lower);
226+
}
227+
228+
Datum
229+
gbt_float8_sortsupport(PG_FUNCTION_ARGS)
230+
{
231+
SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
232+
233+
ssup->comparator = gbt_float8_ssup_cmp;
234+
ssup->ssup_extra = NULL;
235+
236+
PG_RETURN_VOID();
237+
}

0 commit comments

Comments
 (0)