Skip to content

Commit 3976899

Browse files
committed
Fix storage size for btree_gist interval indexes. Fix penalty
calculations for interval and time/timetz to behave sanely for both integer and float timestamps; up to now I think it's been doing something pretty strange...
1 parent a536b2d commit 3976899

File tree

5 files changed

+42
-37
lines changed

5 files changed

+42
-37
lines changed

contrib/btree_gist/btree_gist.sql.in

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,20 @@ INPUT = gbtreekey16_in,
4949
OUTPUT = gbtreekey16_out
5050
);
5151

52-
CREATE FUNCTION gbtreekey24_in(cstring)
53-
RETURNS gbtreekey24
52+
CREATE FUNCTION gbtreekey32_in(cstring)
53+
RETURNS gbtreekey32
5454
AS 'MODULE_PATHNAME', 'gbtreekey_in'
5555
LANGUAGE 'c' WITH (isstrict);
5656

57-
CREATE FUNCTION gbtreekey24_out(gbtreekey24)
57+
CREATE FUNCTION gbtreekey32_out(gbtreekey32)
5858
RETURNS cstring
5959
AS 'MODULE_PATHNAME', 'gbtreekey_out'
6060
LANGUAGE 'c' WITH (isstrict);
6161

62-
CREATE TYPE gbtreekey24 (
63-
INTERNALLENGTH = 24,
64-
INPUT = gbtreekey24_in,
65-
OUTPUT = gbtreekey24_out
62+
CREATE TYPE gbtreekey32 (
63+
INTERNALLENGTH = 32,
64+
INPUT = gbtreekey32_in,
65+
OUTPUT = gbtreekey32_out
6666
);
6767

6868
CREATE FUNCTION gbtreekey_var_in(cstring)
@@ -697,7 +697,7 @@ AS 'MODULE_PATHNAME'
697697
LANGUAGE 'C';
698698

699699
CREATE FUNCTION gbt_intv_union(bytea, internal)
700-
RETURNS gbtreekey24
700+
RETURNS gbtreekey32
701701
AS 'MODULE_PATHNAME'
702702
LANGUAGE 'C';
703703

@@ -722,7 +722,7 @@ AS
722722
FUNCTION 5 gbt_intv_penalty (internal, internal, internal),
723723
FUNCTION 6 gbt_intv_picksplit (internal, internal),
724724
FUNCTION 7 gbt_intv_same (internal, internal, internal),
725-
STORAGE gbtreekey24;
725+
STORAGE gbtreekey32;
726726

727727
--
728728
--

contrib/btree_gist/btree_interval.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,14 @@ gbt_intvkey_cmp(const void *a, const void *b)
7373
static double
7474
intr2num(const Interval *i)
7575
{
76-
double ret = 0.0;
77-
struct pg_tm tm;
78-
fsec_t fsec;
79-
80-
interval2tm(*i, &tm, &fsec);
81-
ret += (tm.tm_year * 360.0 * 86400.0);
82-
ret += (tm.tm_mon * 12.0 * 86400.0);
83-
ret += (tm.tm_mday * 86400.0);
84-
ret += (tm.tm_hour * 3600.0);
85-
ret += (tm.tm_min * 60.0);
86-
ret += (tm.tm_sec);
87-
ret += (fsec / 1000000.0);
88-
89-
return (ret);
76+
return INTERVAL_TO_SEC(i);
9077
}
9178

79+
/*
80+
* INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
81+
* in pg_type. This might be less than sizeof(Interval) if the compiler
82+
* insists on adding alignment padding at the end of the struct.
83+
*/
9284
#define INTERVALSIZE 16
9385

9486
static const gbtree_ninfo tinfo =

contrib/btree_gist/btree_time.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,29 +207,24 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
207207
timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
208208
float *result = (float *) PG_GETARG_POINTER(2);
209209
Interval *intr;
210-
211-
#ifdef HAVE_INT64_TIMESTAMP
212-
int64 res;
213-
214-
#else
215210
double res;
216-
#endif
211+
double res2;
217212

218213
intr = DatumGetIntervalP(DirectFunctionCall2(
219214
time_mi_time,
220215
P_TimeADTGetDatum(newentry->upper),
221216
P_TimeADTGetDatum(origentry->upper)));
222-
223-
/* see interval_larger */
224-
res = Max(intr->time + intr->day * 86400 + intr->month * (30 * 86400), 0);
217+
res = INTERVAL_TO_SEC(intr);
218+
res = Max(res, 0);
225219

226220
intr = DatumGetIntervalP(DirectFunctionCall2(
227221
time_mi_time,
228222
P_TimeADTGetDatum(origentry->lower),
229223
P_TimeADTGetDatum(newentry->lower)));
224+
res2 = INTERVAL_TO_SEC(intr);
225+
res2 = Max(res2, 0);
230226

231-
/* see interval_larger */
232-
res += Max(intr->time + intr->day * 86400 + intr->month * (30 * 86400), 0);
227+
res += res2;
233228

234229
*result = 0.0;
235230

@@ -240,7 +235,7 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
240235
P_TimeADTGetDatum(origentry->upper),
241236
P_TimeADTGetDatum(origentry->lower)));
242237
*result += FLT_MIN;
243-
*result += (float) (res / ((double) (res + intr->time + intr->day * 86400 + intr->month * (30 * 86400))));
238+
*result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
244239
*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
245240
}
246241

contrib/btree_gist/btree_utils_num.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,24 @@ typedef struct
6363
} while (0);
6464

6565

66+
/*
67+
* Convert an Interval to an approximate equivalent number of seconds
68+
* (as a double). Here because we need it for time/timetz as well as
69+
* interval. See interval_cmp_internal for comparison.
70+
*/
71+
#ifdef HAVE_INT64_TIMESTAMP
72+
#define INTERVAL_TO_SEC(ivp) \
73+
(((double) (ivp)->time) / ((double) USECS_PER_SEC) + \
74+
(ivp)->day * (24.0 * SECS_PER_HOUR) + \
75+
(ivp)->month * (30.0 * SECS_PER_DAY))
76+
#else
77+
#define INTERVAL_TO_SEC(ivp) \
78+
((ivp)->time + \
79+
(ivp)->day * (24.0 * SECS_PER_HOUR) + \
80+
(ivp)->month * (30.0 * SECS_PER_DAY))
81+
#endif
82+
83+
6684
extern bool gbt_num_consistent(const GBT_NUMKEY_R * key, const void *query,
6785
const StrategyNumber *strategy, bool is_leaf,
6886
const gbtree_ninfo * tinfo);

contrib/btree_gist/expected/init.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ psql:btree_gist.sql:28: NOTICE: argument type gbtreekey8 is only a shell
1212
psql:btree_gist.sql:39: NOTICE: type "gbtreekey16" is not yet defined
1313
DETAIL: Creating a shell type definition.
1414
psql:btree_gist.sql:44: NOTICE: argument type gbtreekey16 is only a shell
15-
psql:btree_gist.sql:55: NOTICE: type "gbtreekey24" is not yet defined
15+
psql:btree_gist.sql:55: NOTICE: type "gbtreekey32" is not yet defined
1616
DETAIL: Creating a shell type definition.
17-
psql:btree_gist.sql:60: NOTICE: argument type gbtreekey24 is only a shell
17+
psql:btree_gist.sql:60: NOTICE: argument type gbtreekey32 is only a shell
1818
psql:btree_gist.sql:71: NOTICE: type "gbtreekey_var" is not yet defined
1919
DETAIL: Creating a shell type definition.
2020
psql:btree_gist.sql:76: NOTICE: argument type gbtreekey_var is only a shell

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy