3
3
4
4
typedef struct
5
5
{
6
- Interval lower ,
7
- upper ;
6
+ Interval lower , upper ;
8
7
} intvKEY ;
9
8
10
9
11
10
/*
12
11
** Interval ops
13
12
*/
14
13
PG_FUNCTION_INFO_V1 (gbt_intv_compress );
14
+ PG_FUNCTION_INFO_V1 (gbt_intv_decompress );
15
15
PG_FUNCTION_INFO_V1 (gbt_intv_union );
16
16
PG_FUNCTION_INFO_V1 (gbt_intv_picksplit );
17
17
PG_FUNCTION_INFO_V1 (gbt_intv_consistent );
18
18
PG_FUNCTION_INFO_V1 (gbt_intv_penalty );
19
19
PG_FUNCTION_INFO_V1 (gbt_intv_same );
20
20
21
21
Datum gbt_intv_compress (PG_FUNCTION_ARGS );
22
+ Datum gbt_intv_decompress (PG_FUNCTION_ARGS );
22
23
Datum gbt_intv_union (PG_FUNCTION_ARGS );
23
24
Datum gbt_intv_picksplit (PG_FUNCTION_ARGS );
24
25
Datum gbt_intv_consistent (PG_FUNCTION_ARGS );
@@ -28,40 +29,60 @@ Datum gbt_intv_same(PG_FUNCTION_ARGS);
28
29
29
30
static bool gbt_intvgt (const void * a , const void * b )
30
31
{
31
- return DirectFunctionCall2 ( interval_gt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
32
+ return DatumGetBool ( DirectFunctionCall2 ( interval_gt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ) );
32
33
}
33
34
34
35
static bool gbt_intvge (const void * a , const void * b )
35
36
{
36
- return DirectFunctionCall2 ( interval_ge , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
37
+ return DatumGetBool ( DirectFunctionCall2 ( interval_ge , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ) );
37
38
}
38
39
39
40
static bool gbt_intveq (const void * a , const void * b )
40
41
{
41
- return DirectFunctionCall2 ( interval_eq , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
42
+ return DatumGetBool ( DirectFunctionCall2 ( interval_eq , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ) );
42
43
}
43
44
44
45
static bool gbt_intvle (const void * a , const void * b )
45
46
{
46
- return DirectFunctionCall2 ( interval_le , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
47
+ return DatumGetBool ( DirectFunctionCall2 ( interval_le , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ) );
47
48
}
48
49
49
50
static bool gbt_intvlt (const void * a , const void * b )
50
51
{
51
- return DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) );
52
+ return DatumGetBool ( DirectFunctionCall2 ( interval_lt , IntervalPGetDatum ( a ) , IntervalPGetDatum ( b ) ) );
52
53
}
53
54
54
55
static int
55
56
gbt_intvkey_cmp (const void * a , const void * b )
56
57
{
57
58
return DatumGetInt32 (
58
59
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 )
61
62
)
62
63
);
63
64
}
64
65
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
+
65
86
static const gbtree_ninfo tinfo =
66
87
{
67
88
gbt_t_intv ,
@@ -84,10 +105,51 @@ Datum
84
105
gbt_intv_compress (PG_FUNCTION_ARGS )
85
106
{
86
107
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
+
89
130
}
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
+
91
153
92
154
Datum
93
155
gbt_intv_consistent (PG_FUNCTION_ARGS )
@@ -97,6 +159,7 @@ gbt_intv_consistent(PG_FUNCTION_ARGS)
97
159
intvKEY * kkk = (intvKEY * ) DatumGetPointer (entry -> key );
98
160
GBT_NUMKEY_R key ;
99
161
StrategyNumber strategy = (StrategyNumber ) PG_GETARG_UINT16 (2 );
162
+
100
163
key .lower = (GBT_NUMKEY * ) & kkk -> lower ;
101
164
key .upper = (GBT_NUMKEY * ) & kkk -> upper ;
102
165
@@ -121,56 +184,26 @@ gbt_intv_penalty(PG_FUNCTION_ARGS)
121
184
{
122
185
intvKEY * origentry = (intvKEY * ) DatumGetPointer (((GISTENTRY * ) PG_GETARG_POINTER (0 ))-> key );
123
186
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 ;
139
189
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 );
142
194
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 ] );
152
196
153
197
* result = 0.0 ;
154
198
155
199
if ( res > 0 ){
156
-
157
- intr = DatumGetIntervalP (DirectFunctionCall2 (
158
- interval_mi ,
159
- IntervalPGetDatum (& origentry -> upper ),
160
- IntervalPGetDatum (& origentry -> lower )
161
- ));
162
-
163
200
* result += FLT_MIN ;
164
- * result += (float ) ( res / ( ( double ) ( res + intr -> time + intr -> month * ( 30 * 86400 ) ) ) );
201
+ * result += (float ) ( res / ( res + iorg [ 1 ] - iorg [ 0 ] ) );
165
202
* result *= ( FLT_MAX / ( ( (GISTENTRY * ) PG_GETARG_POINTER (0 ))-> rel -> rd_att -> natts + 1 ) );
166
-
167
- pfree ( intr );
168
-
169
203
}
170
204
171
205
PG_RETURN_POINTER (result );
172
206
173
-
174
207
}
175
208
176
209
Datum
0 commit comments