Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * contrib/btree_gist/btree_date.c
3 : : */
4 : : #include "postgres.h"
5 : :
6 : : #include "btree_gist.h"
7 : : #include "btree_utils_num.h"
8 : : #include "utils/fmgrprotos.h"
9 : : #include "utils/date.h"
10 : : #include "utils/rel.h"
11 : : #include "utils/sortsupport.h"
12 : :
13 : : typedef struct
14 : : {
15 : : DateADT lower;
16 : : DateADT upper;
17 : : } dateKEY;
18 : :
19 : : /* GiST support functions */
7961 teodor@sigaev.ru 20 :CBC 4 : PG_FUNCTION_INFO_V1(gbt_date_compress);
4006 heikki.linnakangas@i 21 : 4 : PG_FUNCTION_INFO_V1(gbt_date_fetch);
7961 teodor@sigaev.ru 22 : 4 : PG_FUNCTION_INFO_V1(gbt_date_union);
23 : 4 : PG_FUNCTION_INFO_V1(gbt_date_picksplit);
24 : 4 : PG_FUNCTION_INFO_V1(gbt_date_consistent);
5492 tgl@sss.pgh.pa.us 25 : 4 : PG_FUNCTION_INFO_V1(gbt_date_distance);
7961 teodor@sigaev.ru 26 : 4 : PG_FUNCTION_INFO_V1(gbt_date_penalty);
27 : 4 : PG_FUNCTION_INFO_V1(gbt_date_same);
346 heikki.linnakangas@i 28 : 4 : PG_FUNCTION_INFO_V1(gbt_date_sortsupport);
29 : :
30 : : static bool
3281 andrew@dunslane.net 31 : 1357 : gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
32 : : {
2236 alvherre@alvh.no-ip. 33 : 1357 : return DatumGetBool(DirectFunctionCall2(date_gt,
34 : : DateADTGetDatum(*((const DateADT *) a)),
35 : : DateADTGetDatum(*((const DateADT *) b))));
36 : : }
37 : :
38 : : static bool
3281 andrew@dunslane.net 39 : 507 : gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
40 : : {
2236 alvherre@alvh.no-ip. 41 : 507 : return DatumGetBool(DirectFunctionCall2(date_ge,
42 : : DateADTGetDatum(*((const DateADT *) a)),
43 : : DateADTGetDatum(*((const DateADT *) b))));
44 : : }
45 : :
46 : : static bool
3281 andrew@dunslane.net 47 : 272 : gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
48 : : {
2236 alvherre@alvh.no-ip. 49 : 272 : return DatumGetBool(DirectFunctionCall2(date_eq,
50 : : DateADTGetDatum(*((const DateADT *) a)),
51 : : DateADTGetDatum(*((const DateADT *) b)))
52 : : );
53 : : }
54 : :
55 : : static bool
3281 andrew@dunslane.net 56 : 825 : gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
57 : : {
2236 alvherre@alvh.no-ip. 58 : 825 : return DatumGetBool(DirectFunctionCall2(date_le,
59 : : DateADTGetDatum(*((const DateADT *) a)),
60 : : DateADTGetDatum(*((const DateADT *) b))));
61 : : }
62 : :
63 : : static bool
3281 andrew@dunslane.net 64 : 1629 : gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
65 : : {
2236 alvherre@alvh.no-ip. 66 : 1629 : return DatumGetBool(DirectFunctionCall2(date_lt,
67 : : DateADTGetDatum(*((const DateADT *) a)),
68 : : DateADTGetDatum(*((const DateADT *) b))));
69 : : }
70 : :
71 : :
72 : :
73 : : static int
3281 andrew@dunslane.net 74 : 543 : gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
75 : : {
5299 peter_e@gmx.net 76 : 543 : dateKEY *ia = (dateKEY *) (((const Nsrt *) a)->t);
77 : 543 : dateKEY *ib = (dateKEY *) (((const Nsrt *) b)->t);
78 : : int res;
79 : :
2236 alvherre@alvh.no-ip. 80 : 543 : res = DatumGetInt32(DirectFunctionCall2(date_cmp,
81 : : DateADTGetDatum(ia->lower),
82 : : DateADTGetDatum(ib->lower)));
5947 teodor@sigaev.ru 83 [ + + ]: 543 : if (res == 0)
2236 alvherre@alvh.no-ip. 84 : 5 : return DatumGetInt32(DirectFunctionCall2(date_cmp,
85 : : DateADTGetDatum(ia->upper),
86 : : DateADTGetDatum(ib->upper)));
87 : :
5947 teodor@sigaev.ru 88 : 538 : return res;
89 : : }
90 : :
91 : : static float8
3281 andrew@dunslane.net 92 : 273 : gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
93 : : {
94 : : /* we assume the difference can't overflow */
5453 bruce@momjian.us 95 : 273 : Datum diff = DirectFunctionCall2(date_mi,
96 : : DateADTGetDatum(*((const DateADT *) a)),
97 : : DateADTGetDatum(*((const DateADT *) b)));
98 : :
1255 peter@eisentraut.org 99 : 273 : return (float8) abs(DatumGetInt32(diff));
100 : : }
101 : :
102 : :
103 : : static const gbtree_ninfo tinfo =
104 : : {
105 : : gbt_t_date,
106 : : sizeof(DateADT),
107 : : 8, /* sizeof(gbtreekey8) */
108 : : gbt_dategt,
109 : : gbt_datege,
110 : : gbt_dateeq,
111 : : gbt_datele,
112 : : gbt_datelt,
113 : : gbt_datekey_cmp,
114 : : gdb_date_dist
115 : : };
116 : :
117 : :
5492 tgl@sss.pgh.pa.us 118 : 4 : PG_FUNCTION_INFO_V1(date_dist);
119 : : Datum
120 : 547 : date_dist(PG_FUNCTION_ARGS)
121 : : {
122 : : /* we assume the difference can't overflow */
5453 bruce@momjian.us 123 : 547 : Datum diff = DirectFunctionCall2(date_mi,
124 : : PG_GETARG_DATUM(0),
125 : : PG_GETARG_DATUM(1));
126 : :
1255 peter@eisentraut.org 127 : 547 : PG_RETURN_INT32(abs(DatumGetInt32(diff)));
128 : : }
129 : :
130 : :
131 : : /**************************************************
132 : : * GiST support functions
133 : : **************************************************/
134 : :
135 : : Datum
7961 teodor@sigaev.ru 136 : 546 : gbt_date_compress(PG_FUNCTION_ARGS)
137 : : {
7868 bruce@momjian.us 138 : 546 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
139 : :
4007 heikki.linnakangas@i 140 : 546 : PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
141 : : }
142 : :
143 : : Datum
4006 144 : 272 : gbt_date_fetch(PG_FUNCTION_ARGS)
145 : : {
146 : 272 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
147 : :
148 : 272 : PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
149 : : }
150 : :
151 : : Datum
7961 teodor@sigaev.ru 152 : 1914 : gbt_date_consistent(PG_FUNCTION_ARGS)
153 : : {
7868 bruce@momjian.us 154 : 1914 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
155 : 1914 : DateADT query = PG_GETARG_DATEADT(1);
6544 tgl@sss.pgh.pa.us 156 : 1914 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
157 : : #ifdef NOT_USED
158 : : Oid subtype = PG_GETARG_OID(3);
159 : : #endif
160 : 1914 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
7868 bruce@momjian.us 161 : 1914 : dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
162 : : GBT_NUMKEY_R key;
163 : :
164 : : /* All cases served by this function are exact */
6544 tgl@sss.pgh.pa.us 165 : 1914 : *recheck = false;
166 : :
6121 bruce@momjian.us 167 : 1914 : key.lower = (GBT_NUMKEY *) &kkk->lower;
168 : 1914 : key.upper = (GBT_NUMKEY *) &kkk->upper;
169 : :
472 peter@eisentraut.org 170 : 1914 : PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
171 : : GIST_LEAF(entry), &tinfo,
172 : : fcinfo->flinfo));
173 : : }
174 : :
175 : : Datum
5492 tgl@sss.pgh.pa.us 176 : 274 : gbt_date_distance(PG_FUNCTION_ARGS)
177 : : {
178 : 274 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
179 : 274 : DateADT query = PG_GETARG_DATEADT(1);
180 : : #ifdef NOT_USED
181 : : Oid subtype = PG_GETARG_OID(3);
182 : : #endif
183 : 274 : dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
184 : : GBT_NUMKEY_R key;
185 : :
186 : 274 : key.lower = (GBT_NUMKEY *) &kkk->lower;
187 : 274 : key.upper = (GBT_NUMKEY *) &kkk->upper;
188 : :
472 peter@eisentraut.org 189 : 274 : PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
190 : : &tinfo, fcinfo->flinfo));
191 : : }
192 : :
193 : : Datum
7961 teodor@sigaev.ru 194 : 1 : gbt_date_union(PG_FUNCTION_ARGS)
195 : : {
7868 bruce@momjian.us 196 : 1 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
197 : 1 : void *out = palloc(sizeof(dateKEY));
198 : :
199 : 1 : *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
472 peter@eisentraut.org 200 : 1 : PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
201 : : }
202 : :
203 : : Datum
7961 teodor@sigaev.ru 204 :UBC 0 : gbt_date_penalty(PG_FUNCTION_ARGS)
205 : : {
7868 bruce@momjian.us 206 : 0 : dateKEY *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
207 : 0 : dateKEY *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
208 : 0 : float *result = (float *) PG_GETARG_POINTER(2);
209 : : int32 diff,
210 : : res;
211 : :
2236 alvherre@alvh.no-ip. 212 : 0 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
213 : : DateADTGetDatum(newentry->upper),
214 : : DateADTGetDatum(origentry->upper)));
215 : :
7868 bruce@momjian.us 216 : 0 : res = Max(diff, 0);
217 : :
2236 alvherre@alvh.no-ip. 218 : 0 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
219 : : DateADTGetDatum(origentry->lower),
220 : : DateADTGetDatum(newentry->lower)));
221 : :
7868 bruce@momjian.us 222 : 0 : res += Max(diff, 0);
223 : :
224 : 0 : *result = 0.0;
225 : :
226 [ # # ]: 0 : if (res > 0)
227 : : {
2236 alvherre@alvh.no-ip. 228 : 0 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
229 : : DateADTGetDatum(origentry->upper),
230 : : DateADTGetDatum(origentry->lower)));
7868 bruce@momjian.us 231 : 0 : *result += FLT_MIN;
232 : 0 : *result += (float) (res / ((double) (res + diff)));
233 : 0 : *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
234 : : }
235 : :
236 : 0 : PG_RETURN_POINTER(result);
237 : : }
238 : :
239 : : Datum
7961 teodor@sigaev.ru 240 :CBC 1 : gbt_date_picksplit(PG_FUNCTION_ARGS)
241 : : {
2236 alvherre@alvh.no-ip. 242 : 1 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
243 : : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
244 : : &tinfo, fcinfo->flinfo));
245 : : }
246 : :
247 : : Datum
7961 teodor@sigaev.ru 248 :UBC 0 : gbt_date_same(PG_FUNCTION_ARGS)
249 : : {
7868 bruce@momjian.us 250 : 0 : dateKEY *b1 = (dateKEY *) PG_GETARG_POINTER(0);
251 : 0 : dateKEY *b2 = (dateKEY *) PG_GETARG_POINTER(1);
252 : 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
253 : :
3281 andrew@dunslane.net 254 : 0 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
7868 bruce@momjian.us 255 : 0 : PG_RETURN_POINTER(result);
256 : : }
257 : :
258 : : static int
346 heikki.linnakangas@i 259 :CBC 5364 : gbt_date_ssup_cmp(Datum x, Datum y, SortSupport ssup)
260 : : {
261 : 5364 : dateKEY *akey = (dateKEY *) DatumGetPointer(x);
262 : 5364 : dateKEY *bkey = (dateKEY *) DatumGetPointer(y);
263 : :
264 : : /* for leaf items we expect lower == upper, so only compare lower */
265 : 5364 : return DatumGetInt32(DirectFunctionCall2(date_cmp,
266 : : DateADTGetDatum(akey->lower),
267 : : DateADTGetDatum(bkey->lower)));
268 : : }
269 : :
270 : : Datum
271 : 1 : gbt_date_sortsupport(PG_FUNCTION_ARGS)
272 : : {
273 : 1 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
274 : :
275 : 1 : ssup->comparator = gbt_date_ssup_cmp;
276 : 1 : ssup->ssup_extra = NULL;
277 : :
278 : 1 : PG_RETURN_VOID();
279 : : }
|