4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/timestamp.h"
18 PG_FUNCTION_INFO_V1(gbt_intv_compress
);
19 PG_FUNCTION_INFO_V1(gbt_intv_decompress
);
20 PG_FUNCTION_INFO_V1(gbt_intv_union
);
21 PG_FUNCTION_INFO_V1(gbt_intv_picksplit
);
22 PG_FUNCTION_INFO_V1(gbt_intv_consistent
);
23 PG_FUNCTION_INFO_V1(gbt_intv_penalty
);
24 PG_FUNCTION_INFO_V1(gbt_intv_same
);
26 Datum
gbt_intv_compress(PG_FUNCTION_ARGS
);
27 Datum
gbt_intv_decompress(PG_FUNCTION_ARGS
);
28 Datum
gbt_intv_union(PG_FUNCTION_ARGS
);
29 Datum
gbt_intv_picksplit(PG_FUNCTION_ARGS
);
30 Datum
gbt_intv_consistent(PG_FUNCTION_ARGS
);
31 Datum
gbt_intv_penalty(PG_FUNCTION_ARGS
);
32 Datum
gbt_intv_same(PG_FUNCTION_ARGS
);
36 gbt_intvgt(const void *a
, const void *b
)
38 return DatumGetBool(DirectFunctionCall2(interval_gt
, IntervalPGetDatum(a
), IntervalPGetDatum(b
)));
42 gbt_intvge(const void *a
, const void *b
)
44 return DatumGetBool(DirectFunctionCall2(interval_ge
, IntervalPGetDatum(a
), IntervalPGetDatum(b
)));
48 gbt_intveq(const void *a
, const void *b
)
50 return DatumGetBool(DirectFunctionCall2(interval_eq
, IntervalPGetDatum(a
), IntervalPGetDatum(b
)));
54 gbt_intvle(const void *a
, const void *b
)
56 return DatumGetBool(DirectFunctionCall2(interval_le
, IntervalPGetDatum(a
), IntervalPGetDatum(b
)));
60 gbt_intvlt(const void *a
, const void *b
)
62 return DatumGetBool(DirectFunctionCall2(interval_lt
, IntervalPGetDatum(a
), IntervalPGetDatum(b
)));
66 gbt_intvkey_cmp(const void *a
, const void *b
)
69 DirectFunctionCall2(interval_cmp
,
70 IntervalPGetDatum(((Nsrt
*) a
)->t
),
71 IntervalPGetDatum(((Nsrt
*) b
)->t
)
78 intr2num(const Interval
*i
)
80 return INTERVAL_TO_SEC(i
);
84 * INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
85 * in pg_type. This might be less than sizeof(Interval) if the compiler
86 * insists on adding alignment padding at the end of the struct.
88 #define INTERVALSIZE 16
90 static const gbtree_ninfo tinfo
=
103 /**************************************************
105 **************************************************/
109 gbt_intv_compress(PG_FUNCTION_ARGS
)
111 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
112 GISTENTRY
*retval
= entry
;
114 if (entry
->leafkey
|| INTERVALSIZE
!= sizeof(Interval
))
116 char *r
= (char *) palloc(2 * INTERVALSIZE
);
118 retval
= palloc(sizeof(GISTENTRY
));
122 Interval
*key
= DatumGetIntervalP(entry
->key
);
124 memcpy((void *) r
, (void *) key
, INTERVALSIZE
);
125 memcpy((void *) (r
+ INTERVALSIZE
), (void *) key
, INTERVALSIZE
);
129 intvKEY
*key
= (intvKEY
*) DatumGetPointer(entry
->key
);
131 memcpy(r
, &key
->lower
, INTERVALSIZE
);
132 memcpy(r
+ INTERVALSIZE
, &key
->upper
, INTERVALSIZE
);
134 gistentryinit(*retval
, PointerGetDatum(r
),
135 entry
->rel
, entry
->page
,
136 entry
->offset
, FALSE
);
139 PG_RETURN_POINTER(retval
);
144 gbt_intv_decompress(PG_FUNCTION_ARGS
)
146 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
147 GISTENTRY
*retval
= entry
;
149 if (INTERVALSIZE
!= sizeof(Interval
))
151 intvKEY
*r
= palloc(sizeof(intvKEY
));
152 char *key
= DatumGetPointer(entry
->key
);
154 retval
= palloc(sizeof(GISTENTRY
));
155 memcpy(&r
->lower
, key
, INTERVALSIZE
);
156 memcpy(&r
->upper
, key
+ INTERVALSIZE
, INTERVALSIZE
);
158 gistentryinit(*retval
, PointerGetDatum(r
),
159 entry
->rel
, entry
->page
,
160 entry
->offset
, FALSE
);
162 PG_RETURN_POINTER(retval
);
167 gbt_intv_consistent(PG_FUNCTION_ARGS
)
169 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
170 Interval
*query
= PG_GETARG_INTERVAL_P(1);
171 StrategyNumber strategy
= (StrategyNumber
) PG_GETARG_UINT16(2);
173 /* Oid subtype = PG_GETARG_OID(3); */
174 bool *recheck
= (bool *) PG_GETARG_POINTER(4);
175 intvKEY
*kkk
= (intvKEY
*) DatumGetPointer(entry
->key
);
178 /* All cases served by this function are exact */
181 key
.lower
= (GBT_NUMKEY
*) &kkk
->lower
;
182 key
.upper
= (GBT_NUMKEY
*) &kkk
->upper
;
185 gbt_num_consistent(&key
, (void *) query
, &strategy
, GIST_LEAF(entry
), &tinfo
)
191 gbt_intv_union(PG_FUNCTION_ARGS
)
193 GistEntryVector
*entryvec
= (GistEntryVector
*) PG_GETARG_POINTER(0);
194 void *out
= palloc(sizeof(intvKEY
));
196 *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY
);
197 PG_RETURN_POINTER(gbt_num_union((void *) out
, entryvec
, &tinfo
));
202 gbt_intv_penalty(PG_FUNCTION_ARGS
)
204 intvKEY
*origentry
= (intvKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(0))->key
);
205 intvKEY
*newentry
= (intvKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(1))->key
);
206 float *result
= (float *) PG_GETARG_POINTER(2);
210 iorg
[0] = intr2num(&origentry
->lower
);
211 iorg
[1] = intr2num(&origentry
->upper
);
212 inew
[0] = intr2num(&newentry
->lower
);
213 inew
[1] = intr2num(&newentry
->upper
);
215 penalty_num(result
, iorg
[0], iorg
[1], inew
[0], inew
[1]);
217 PG_RETURN_POINTER(result
);
222 gbt_intv_picksplit(PG_FUNCTION_ARGS
)
224 PG_RETURN_POINTER(gbt_num_picksplit(
225 (GistEntryVector
*) PG_GETARG_POINTER(0),
226 (GIST_SPLITVEC
*) PG_GETARG_POINTER(1),
232 gbt_intv_same(PG_FUNCTION_ARGS
)
234 intvKEY
*b1
= (intvKEY
*) PG_GETARG_POINTER(0);
235 intvKEY
*b2
= (intvKEY
*) PG_GETARG_POINTER(1);
236 bool *result
= (bool *) PG_GETARG_POINTER(2);
238 *result
= gbt_num_same((void *) b1
, (void *) b2
, &tinfo
);
239 PG_RETURN_POINTER(result
);