Skip to content

Commit 7b81988

Browse files
committed
- Add aligment of variable data types
- Add aligment for interval data types - Avoid floating point overflow in penalty functions Janko Richter <jankorichter@yahoo.de> and teodor
1 parent 921d749 commit 7b81988

17 files changed

+161
-110
lines changed

contrib/btree_gist/btree_cash.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ gbt_cash_penalty(PG_FUNCTION_ARGS)
126126

127127
*result = 0.0;
128128

129-
res = Max(newentry->upper - origentry->upper, 0) +
130-
Max(origentry->lower - newentry->lower, 0);
129+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
131130

132131
if ( res > 0 ){
133132
*result += FLT_MIN ;

contrib/btree_gist/btree_date.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,10 @@ gbt_date_consistent(PG_FUNCTION_ARGS)
112112
dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
113113
GBT_NUMKEY_R key ;
114114
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
115+
115116
key.lower = (GBT_NUMKEY*) &kkk->lower ;
116117
key.upper = (GBT_NUMKEY*) &kkk->upper ;
117-
118+
118119
PG_RETURN_BOOL(
119120
gbt_num_consistent( &key, (void*)&query,&strategy,GIST_LEAF(entry),&tinfo)
120121
);

contrib/btree_gist/btree_float4.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ Datum
9191
gbt_float4_consistent(PG_FUNCTION_ARGS)
9292
{
9393
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
94-
float4 query = PG_GETARG_FLOAT4(1);
95-
float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key);
94+
float4 query = PG_GETARG_FLOAT4(1);
95+
float4KEY *kkk = (float4KEY *) DatumGetPointer(entry->key);
9696
GBT_NUMKEY_R key ;
9797
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
9898
key.lower = (GBT_NUMKEY*) &kkk->lower ;
@@ -125,8 +125,7 @@ gbt_float4_penalty(PG_FUNCTION_ARGS)
125125

126126
*result = 0.0;
127127

128-
res = Max(newentry->upper - origentry->upper, 0) +
129-
Max(origentry->lower - newentry->lower, 0);
128+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
130129

131130
if ( res > 0 ){
132131
*result += FLT_MIN ;

contrib/btree_gist/btree_float8.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ gbt_float8_compress(PG_FUNCTION_ARGS)
9191
Datum
9292
gbt_float8_consistent(PG_FUNCTION_ARGS)
9393
{
94+
9495
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
9596
float8 query = PG_GETARG_FLOAT8(1);
9697
float8KEY *kkk = (float8KEY *) DatumGetPointer(entry->key);
@@ -126,8 +127,7 @@ gbt_float8_penalty(PG_FUNCTION_ARGS)
126127

127128
*result = 0.0;
128129

129-
res = Max(newentry->upper - origentry->upper, 0) +
130-
Max(origentry->lower - newentry->lower, 0);
130+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
131131

132132
if ( res > 0 ){
133133
*result += FLT_MIN ;

contrib/btree_gist/btree_gist.sql.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,11 @@ RETURNS internal
676676
AS 'MODULE_PATHNAME'
677677
LANGUAGE 'C';
678678

679+
CREATE FUNCTION gbt_intv_decompress(internal)
680+
RETURNS internal
681+
AS 'MODULE_PATHNAME'
682+
LANGUAGE 'C';
683+
679684
CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
680685
RETURNS internal
681686
AS 'MODULE_PATHNAME'
@@ -708,7 +713,7 @@ AS
708713
FUNCTION 1 gbt_intv_consistent (internal, interval, int2),
709714
FUNCTION 2 gbt_intv_union (bytea, internal),
710715
FUNCTION 3 gbt_intv_compress (internal),
711-
FUNCTION 4 gbt_decompress (internal),
716+
FUNCTION 4 gbt_intv_decompress (internal),
712717
FUNCTION 5 gbt_intv_penalty (internal, internal, internal),
713718
FUNCTION 6 gbt_intv_picksplit (internal, internal),
714719
FUNCTION 7 gbt_intv_same (internal, internal, internal),

contrib/btree_gist/btree_inet.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ gbt_inet_consistent_internal (
134134
){
135135
inetKEY *kkk = (inetKEY *) DatumGetPointer(entry->key);
136136
GBT_NUMKEY_R key ;
137+
137138
key.lower = (GBT_NUMKEY*) &kkk->lower ;
138139
key.upper = (GBT_NUMKEY*) &kkk->upper ;
139-
140+
140141
return (
141142
gbt_num_consistent( &key, (void*)query,strategy,GIST_LEAF(entry),&tinfo)
142143
);
@@ -189,8 +190,7 @@ gbt_inet_penalty(PG_FUNCTION_ARGS)
189190

190191
*result = 0.0;
191192

192-
res = Max(newentry->upper - origentry->upper, 0) +
193-
Max(origentry->lower - newentry->lower, 0);
193+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
194194

195195
if ( res > 0 ){
196196
*result += FLT_MIN ;

contrib/btree_gist/btree_int2.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ gbt_int2_penalty(PG_FUNCTION_ARGS)
128128

129129
*result = 0.0;
130130

131-
res = Max(newentry->upper - origentry->upper, 0) +
132-
Max(origentry->lower - newentry->lower, 0);
131+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
133132

134133
if ( res > 0 ){
135134
*result += FLT_MIN ;

contrib/btree_gist/btree_int4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ gbt_int4_compress(PG_FUNCTION_ARGS)
9191
Datum
9292
gbt_int4_consistent(PG_FUNCTION_ARGS)
9393
{
94+
9495
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
9596
int32 query = PG_GETARG_INT32(1);
9697
int32KEY *kkk = (int32KEY *) DatumGetPointer(entry->key);
@@ -125,8 +126,7 @@ gbt_int4_penalty(PG_FUNCTION_ARGS)
125126

126127
*result = 0.0;
127128

128-
res = Max(newentry->upper - origentry->upper, 0) +
129-
Max(origentry->lower - newentry->lower, 0);
129+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
130130

131131
if ( res > 0 ){
132132
*result += FLT_MIN ;

contrib/btree_gist/btree_int8.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ gbt_int8_penalty(PG_FUNCTION_ARGS)
125125

126126
*result = 0.0;
127127

128-
res = Max(newentry->upper - origentry->upper, 0) +
129-
Max(origentry->lower - newentry->lower, 0);
128+
penalty_range_enlarge ( origentry->lower, origentry->upper, newentry->lower, newentry->upper );
130129

131130
if ( res > 0 ){
132131
*result += FLT_MIN ;

contrib/btree_gist/btree_interval.c

Lines changed: 83 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33

44
typedef struct
55
{
6-
Interval lower,
7-
upper;
6+
Interval lower, upper;
87
} intvKEY;
98

109

1110
/*
1211
** Interval ops
1312
*/
1413
PG_FUNCTION_INFO_V1(gbt_intv_compress);
14+
PG_FUNCTION_INFO_V1(gbt_intv_decompress);
1515
PG_FUNCTION_INFO_V1(gbt_intv_union);
1616
PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
1717
PG_FUNCTION_INFO_V1(gbt_intv_consistent);
1818
PG_FUNCTION_INFO_V1(gbt_intv_penalty);
1919
PG_FUNCTION_INFO_V1(gbt_intv_same);
2020

2121
Datum gbt_intv_compress(PG_FUNCTION_ARGS);
22+
Datum gbt_intv_decompress(PG_FUNCTION_ARGS);
2223
Datum gbt_intv_union(PG_FUNCTION_ARGS);
2324
Datum gbt_intv_picksplit(PG_FUNCTION_ARGS);
2425
Datum gbt_intv_consistent(PG_FUNCTION_ARGS);
@@ -28,40 +29,60 @@ Datum gbt_intv_same(PG_FUNCTION_ARGS);
2829

2930
static bool gbt_intvgt (const void *a, const void *b)
3031
{
31-
return DirectFunctionCall2 ( interval_gt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
32+
return DatumGetBool(DirectFunctionCall2 ( interval_gt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ));
3233
}
3334

3435
static bool gbt_intvge (const void *a, const void *b)
3536
{
36-
return DirectFunctionCall2 ( interval_ge , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
37+
return DatumGetBool(DirectFunctionCall2 ( interval_ge , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ));
3738
}
3839

3940
static bool gbt_intveq (const void *a, const void *b)
4041
{
41-
return DirectFunctionCall2 ( interval_eq , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
42+
return DatumGetBool(DirectFunctionCall2 ( interval_eq , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ));
4243
}
4344

4445
static bool gbt_intvle (const void *a, const void *b)
4546
{
46-
return DirectFunctionCall2 ( interval_le , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
47+
return DatumGetBool(DirectFunctionCall2 ( interval_le , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ));
4748
}
4849

4950
static bool gbt_intvlt (const void *a, const void *b)
5051
{
51-
return DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
52+
return DatumGetBool(DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ));
5253
}
5354

5455
static int
5556
gbt_intvkey_cmp(const void *a, const void *b)
5657
{
5758
return DatumGetInt32 (
5859
DirectFunctionCall2 ( interval_cmp ,
59-
IntervalPGetDatum(&((Nsrt *) a)->t[0]) ,
60-
IntervalPGetDatum(&((Nsrt *) b)->t[0])
60+
IntervalPGetDatum(((Nsrt *) a)->t) ,
61+
IntervalPGetDatum(((Nsrt *) b)->t)
6162
)
6263
);
6364
}
6465

66+
67+
static double intr2num ( const Interval * i )
68+
{
69+
double ret = 0.0;
70+
struct pg_tm tm;
71+
fsec_t fsec;
72+
interval2tm( *i, &tm, &fsec);
73+
ret += ( tm.tm_year * 360.0 * 86400.0 ) ;
74+
ret += ( tm.tm_mon * 12.0 * 86400.0 ) ;
75+
ret += ( tm.tm_mday * 86400.0 ) ;
76+
ret += ( tm.tm_hour * 3600.0 ) ;
77+
ret += ( tm.tm_min * 60.0 ) ;
78+
ret += ( tm.tm_sec ) ;
79+
ret += ( fsec / 1000000.0 );
80+
81+
return ( ret );
82+
}
83+
84+
#define INTERVALSIZE 12
85+
6586
static const gbtree_ninfo tinfo =
6687
{
6788
gbt_t_intv,
@@ -84,10 +105,51 @@ Datum
84105
gbt_intv_compress(PG_FUNCTION_ARGS)
85106
{
86107
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
87-
GISTENTRY *retval = NULL;
88-
PG_RETURN_POINTER( gbt_num_compress( retval , entry , &tinfo ));
108+
GISTENTRY *retval = entry;
109+
if ( entry->leafkey || INTERVALSIZE != sizeof(Interval) ) {
110+
char *r = ( char * ) palloc(2 * INTERVALSIZE);
111+
112+
retval = palloc(sizeof(GISTENTRY));
113+
114+
if ( entry->leafkey ) {
115+
Interval *key = DatumGetIntervalP(entry->key);
116+
memcpy( (void*) r , (void*)key, INTERVALSIZE);
117+
memcpy( (void*)(r + INTERVALSIZE), (void*)key, INTERVALSIZE);
118+
} else {
119+
intvKEY *key = ( intvKEY * ) DatumGetPointer(entry->key);
120+
memcpy(r, &key->lower, INTERVALSIZE);
121+
memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
122+
}
123+
gistentryinit(*retval, PointerGetDatum(r),
124+
entry->rel, entry->page,
125+
entry->offset, 2 * INTERVALSIZE, FALSE);
126+
}
127+
128+
PG_RETURN_POINTER(retval);
129+
89130
}
90-
131+
132+
Datum
133+
gbt_intv_decompress(PG_FUNCTION_ARGS)
134+
{
135+
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
136+
GISTENTRY *retval = entry;
137+
138+
if ( INTERVALSIZE != sizeof(Interval) ) {
139+
intvKEY *r = palloc(sizeof(intvKEY));
140+
char *key = DatumGetPointer(entry->key);
141+
142+
retval = palloc(sizeof(GISTENTRY));
143+
memcpy( &r->lower, key, INTERVALSIZE);
144+
memcpy( &r->upper, key+ INTERVALSIZE, INTERVALSIZE);
145+
146+
gistentryinit(*retval, PointerGetDatum(r),
147+
entry->rel, entry->page,
148+
entry->offset, sizeof(intvKEY), FALSE);
149+
}
150+
PG_RETURN_POINTER(retval);
151+
}
152+
91153

92154
Datum
93155
gbt_intv_consistent(PG_FUNCTION_ARGS)
@@ -97,6 +159,7 @@ gbt_intv_consistent(PG_FUNCTION_ARGS)
97159
intvKEY *kkk = (intvKEY *) DatumGetPointer(entry->key);
98160
GBT_NUMKEY_R key ;
99161
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
162+
100163
key.lower = (GBT_NUMKEY*) &kkk->lower ;
101164
key.upper = (GBT_NUMKEY*) &kkk->upper ;
102165

@@ -121,56 +184,26 @@ gbt_intv_penalty(PG_FUNCTION_ARGS)
121184
{
122185
intvKEY *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
123186
intvKEY *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
124-
float *result = (float *) PG_GETARG_POINTER(2);
125-
Interval *intr;
126-
#ifdef HAVE_INT64_TIMESTAMP
127-
int64 res;
128-
#else
129-
double res;
130-
#endif
131-
132-
intr = DatumGetIntervalP(DirectFunctionCall2(
133-
interval_mi,
134-
IntervalPGetDatum(&newentry->upper),
135-
IntervalPGetDatum(&origentry->upper)
136-
));
137-
138-
/* see interval_larger */
187+
float *result = (float *) PG_GETARG_POINTER(2);
188+
double iorg[2], inew[2], res;
139189

140-
res = Max(intr->time + intr->month * (30 * 86400), 0);
141-
pfree(intr);
190+
iorg[0] = intr2num ( &origentry->lower );
191+
iorg[1] = intr2num ( &origentry->upper );
192+
inew[0] = intr2num ( &newentry->lower );
193+
inew[1] = intr2num ( &newentry->upper );
142194

143-
intr = DatumGetIntervalP(DirectFunctionCall2(
144-
interval_mi,
145-
IntervalPGetDatum(&origentry->lower),
146-
IntervalPGetDatum(&newentry->lower)
147-
));
148-
149-
/* see interval_larger */
150-
res += Max(intr->time + intr->month * (30 * 86400), 0);
151-
pfree(intr);
195+
penalty_range_enlarge ( iorg[0], iorg[1], inew[0], inew[1] );
152196

153197
*result = 0.0;
154198

155199
if ( res > 0 ){
156-
157-
intr = DatumGetIntervalP(DirectFunctionCall2(
158-
interval_mi,
159-
IntervalPGetDatum(&origentry->upper),
160-
IntervalPGetDatum(&origentry->lower)
161-
));
162-
163200
*result += FLT_MIN ;
164-
*result += (float) ( res / ( (double) ( res + intr->time + intr->month * (30 * 86400) ) ) );
201+
*result += (float) ( res / ( res + iorg[1] - iorg[0] ) );
165202
*result *= ( FLT_MAX / ( ( (GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1 ) );
166-
167-
pfree ( intr );
168-
169203
}
170204

171205
PG_RETURN_POINTER(result);
172206

173-
174207
}
175208

176209
Datum

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