33
44typedef struct
55{
6- Interval lower ,
7- upper ;
6+ Interval lower , upper ;
87} intvKEY ;
98
109
1110/*
1211** Interval ops
1312*/
1413PG_FUNCTION_INFO_V1 (gbt_intv_compress );
14+ PG_FUNCTION_INFO_V1 (gbt_intv_decompress );
1515PG_FUNCTION_INFO_V1 (gbt_intv_union );
1616PG_FUNCTION_INFO_V1 (gbt_intv_picksplit );
1717PG_FUNCTION_INFO_V1 (gbt_intv_consistent );
1818PG_FUNCTION_INFO_V1 (gbt_intv_penalty );
1919PG_FUNCTION_INFO_V1 (gbt_intv_same );
2020
2121Datum gbt_intv_compress (PG_FUNCTION_ARGS );
22+ Datum gbt_intv_decompress (PG_FUNCTION_ARGS );
2223Datum gbt_intv_union (PG_FUNCTION_ARGS );
2324Datum gbt_intv_picksplit (PG_FUNCTION_ARGS );
2425Datum gbt_intv_consistent (PG_FUNCTION_ARGS );
@@ -28,40 +29,60 @@ Datum gbt_intv_same(PG_FUNCTION_ARGS);
2829
2930static 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
3435static 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
3940static 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
4445static 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
4950static 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
5455static int
5556gbt_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+
6586static const gbtree_ninfo tinfo =
6687{
6788 gbt_t_intv ,
@@ -84,10 +105,51 @@ Datum
84105gbt_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
92154Datum
93155gbt_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
176209Datum
0 commit comments