Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+1-2
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

+2-1
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

+3-4
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

+2-2
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

+6-1
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

+3-3
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

+1-2
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

+2-2
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

+1-2
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

+83-50
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)