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/builtins.h"
9 : : #include "utils/date.h"
10 : :
11 : : typedef struct
12 : : {
13 : : DateADT lower;
14 : : DateADT upper;
15 : : } dateKEY;
16 : :
17 : : /*
18 : : ** date ops
19 : : */
7261 teodor@sigaev.ru 20 :CBC 2 : PG_FUNCTION_INFO_V1(gbt_date_compress);
3306 heikki.linnakangas@i 21 : 2 : PG_FUNCTION_INFO_V1(gbt_date_fetch);
7261 teodor@sigaev.ru 22 : 2 : PG_FUNCTION_INFO_V1(gbt_date_union);
23 : 2 : PG_FUNCTION_INFO_V1(gbt_date_picksplit);
24 : 2 : PG_FUNCTION_INFO_V1(gbt_date_consistent);
4792 tgl@sss.pgh.pa.us 25 : 2 : PG_FUNCTION_INFO_V1(gbt_date_distance);
7261 teodor@sigaev.ru 26 : 2 : PG_FUNCTION_INFO_V1(gbt_date_penalty);
27 : 2 : PG_FUNCTION_INFO_V1(gbt_date_same);
28 : :
29 : : static bool
2581 andrew@dunslane.net 30 : 1189 : gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
31 : : {
1536 alvherre@alvh.no-ip. 32 : 1189 : return DatumGetBool(DirectFunctionCall2(date_gt,
33 : : DateADTGetDatum(*((const DateADT *) a)),
34 : : DateADTGetDatum(*((const DateADT *) b))));
35 : : }
36 : :
37 : : static bool
2581 andrew@dunslane.net 38 : 516 : gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
39 : : {
1536 alvherre@alvh.no-ip. 40 : 516 : return DatumGetBool(DirectFunctionCall2(date_ge,
41 : : DateADTGetDatum(*((const DateADT *) a)),
42 : : DateADTGetDatum(*((const DateADT *) b))));
43 : : }
44 : :
45 : : static bool
2581 andrew@dunslane.net 46 : 700 : gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
47 : : {
1536 alvherre@alvh.no-ip. 48 : 700 : return DatumGetBool(DirectFunctionCall2(date_eq,
49 : : DateADTGetDatum(*((const DateADT *) a)),
50 : : DateADTGetDatum(*((const DateADT *) b)))
51 : : );
52 : : }
53 : :
54 : : static bool
2581 andrew@dunslane.net 55 : 834 : gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
56 : : {
1536 alvherre@alvh.no-ip. 57 : 834 : return DatumGetBool(DirectFunctionCall2(date_le,
58 : : DateADTGetDatum(*((const DateADT *) a)),
59 : : DateADTGetDatum(*((const DateADT *) b))));
60 : : }
61 : :
62 : : static bool
2581 andrew@dunslane.net 63 : 1452 : gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
64 : : {
1536 alvherre@alvh.no-ip. 65 : 1452 : return DatumGetBool(DirectFunctionCall2(date_lt,
66 : : DateADTGetDatum(*((const DateADT *) a)),
67 : : DateADTGetDatum(*((const DateADT *) b))));
68 : : }
69 : :
70 : :
71 : :
72 : : static int
2581 andrew@dunslane.net 73 : 3109 : gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
74 : : {
4599 peter_e@gmx.net 75 : 3109 : dateKEY *ia = (dateKEY *) (((const Nsrt *) a)->t);
76 : 3109 : dateKEY *ib = (dateKEY *) (((const Nsrt *) b)->t);
77 : : int res;
78 : :
1536 alvherre@alvh.no-ip. 79 : 3109 : res = DatumGetInt32(DirectFunctionCall2(date_cmp,
80 : : DateADTGetDatum(ia->lower),
81 : : DateADTGetDatum(ib->lower)));
5247 teodor@sigaev.ru 82 [ + + ]: 3109 : if (res == 0)
1536 alvherre@alvh.no-ip. 83 : 1 : return DatumGetInt32(DirectFunctionCall2(date_cmp,
84 : : DateADTGetDatum(ia->upper),
85 : : DateADTGetDatum(ib->upper)));
86 : :
5247 teodor@sigaev.ru 87 : 3108 : return res;
88 : : }
89 : :
90 : : static float8
2581 andrew@dunslane.net 91 : 282 : gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
92 : : {
93 : : /* we assume the difference can't overflow */
4753 bruce@momjian.us 94 : 282 : Datum diff = DirectFunctionCall2(date_mi,
95 : : DateADTGetDatum(*((const DateADT *) a)),
96 : : DateADTGetDatum(*((const DateADT *) b)));
97 : :
555 peter@eisentraut.org 98 : 282 : return (float8) abs(DatumGetInt32(diff));
99 : : }
100 : :
101 : :
102 : : static const gbtree_ninfo tinfo =
103 : : {
104 : : gbt_t_date,
105 : : sizeof(DateADT),
106 : : 8, /* sizeof(gbtreekey8) */
107 : : gbt_dategt,
108 : : gbt_datege,
109 : : gbt_dateeq,
110 : : gbt_datele,
111 : : gbt_datelt,
112 : : gbt_datekey_cmp,
113 : : gdb_date_dist
114 : : };
115 : :
116 : :
4792 tgl@sss.pgh.pa.us 117 : 2 : PG_FUNCTION_INFO_V1(date_dist);
118 : : Datum
119 : 547 : date_dist(PG_FUNCTION_ARGS)
120 : : {
121 : : /* we assume the difference can't overflow */
4753 bruce@momjian.us 122 : 547 : Datum diff = DirectFunctionCall2(date_mi,
123 : : PG_GETARG_DATUM(0),
124 : : PG_GETARG_DATUM(1));
125 : :
555 peter@eisentraut.org 126 : 547 : PG_RETURN_INT32(abs(DatumGetInt32(diff)));
127 : : }
128 : :
129 : :
130 : : /**************************************************
131 : : * date ops
132 : : **************************************************/
133 : :
134 : :
135 : :
136 : : Datum
7261 teodor@sigaev.ru 137 : 548 : gbt_date_compress(PG_FUNCTION_ARGS)
138 : : {
7168 bruce@momjian.us 139 : 548 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
140 : :
3307 heikki.linnakangas@i 141 : 548 : PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
142 : : }
143 : :
144 : : Datum
3306 145 : 281 : gbt_date_fetch(PG_FUNCTION_ARGS)
146 : : {
147 : 281 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
148 : :
149 : 281 : PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
150 : : }
151 : :
152 : : Datum
7261 teodor@sigaev.ru 153 : 1941 : gbt_date_consistent(PG_FUNCTION_ARGS)
154 : : {
7168 bruce@momjian.us 155 : 1941 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
156 : 1941 : DateADT query = PG_GETARG_DATEADT(1);
5844 tgl@sss.pgh.pa.us 157 : 1941 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
158 : :
159 : : /* Oid subtype = PG_GETARG_OID(3); */
160 : 1941 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
7168 bruce@momjian.us 161 : 1941 : dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
162 : : GBT_NUMKEY_R key;
163 : :
164 : : /* All cases served by this function are exact */
5844 tgl@sss.pgh.pa.us 165 : 1941 : *recheck = false;
166 : :
5421 bruce@momjian.us 167 : 1941 : key.lower = (GBT_NUMKEY *) &kkk->lower;
168 : 1941 : key.upper = (GBT_NUMKEY *) &kkk->upper;
169 : :
1536 alvherre@alvh.no-ip. 170 : 1941 : PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
171 : : GIST_LEAF(entry), &tinfo,
172 : : fcinfo->flinfo));
173 : : }
174 : :
175 : :
176 : : Datum
4792 tgl@sss.pgh.pa.us 177 : 283 : gbt_date_distance(PG_FUNCTION_ARGS)
178 : : {
179 : 283 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
180 : 283 : DateADT query = PG_GETARG_DATEADT(1);
181 : :
182 : : /* Oid subtype = PG_GETARG_OID(3); */
183 : 283 : dateKEY *kkk = (dateKEY *) DatumGetPointer(entry->key);
184 : : GBT_NUMKEY_R key;
185 : :
186 : 283 : key.lower = (GBT_NUMKEY *) &kkk->lower;
187 : 283 : key.upper = (GBT_NUMKEY *) &kkk->upper;
188 : :
1536 alvherre@alvh.no-ip. 189 : 283 : PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
190 : : &tinfo, fcinfo->flinfo));
191 : : }
192 : :
193 : :
194 : : Datum
7261 teodor@sigaev.ru 195 : 211 : gbt_date_union(PG_FUNCTION_ARGS)
196 : : {
7168 bruce@momjian.us 197 : 211 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
198 : 211 : void *out = palloc(sizeof(dateKEY));
199 : :
200 : 211 : *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
2581 andrew@dunslane.net 201 : 211 : PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
202 : : }
203 : :
204 : :
205 : : Datum
7261 teodor@sigaev.ru 206 : 339 : gbt_date_penalty(PG_FUNCTION_ARGS)
207 : : {
7168 bruce@momjian.us 208 : 339 : dateKEY *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
209 : 339 : dateKEY *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
210 : 339 : float *result = (float *) PG_GETARG_POINTER(2);
211 : : int32 diff,
212 : : res;
213 : :
1536 alvherre@alvh.no-ip. 214 : 339 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
215 : : DateADTGetDatum(newentry->upper),
216 : : DateADTGetDatum(origentry->upper)));
217 : :
7168 bruce@momjian.us 218 : 339 : res = Max(diff, 0);
219 : :
1536 alvherre@alvh.no-ip. 220 : 339 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
221 : : DateADTGetDatum(origentry->lower),
222 : : DateADTGetDatum(newentry->lower)));
223 : :
7168 bruce@momjian.us 224 : 339 : res += Max(diff, 0);
225 : :
226 : 339 : *result = 0.0;
227 : :
228 [ + + ]: 339 : if (res > 0)
229 : : {
1536 alvherre@alvh.no-ip. 230 : 130 : diff = DatumGetInt32(DirectFunctionCall2(date_mi,
231 : : DateADTGetDatum(origentry->upper),
232 : : DateADTGetDatum(origentry->lower)));
7168 bruce@momjian.us 233 : 130 : *result += FLT_MIN;
234 : 130 : *result += (float) (res / ((double) (res + diff)));
235 : 130 : *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
236 : : }
237 : :
238 : 339 : PG_RETURN_POINTER(result);
239 : : }
240 : :
241 : :
242 : : Datum
7261 teodor@sigaev.ru 243 : 1 : gbt_date_picksplit(PG_FUNCTION_ARGS)
244 : : {
1536 alvherre@alvh.no-ip. 245 : 1 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
246 : : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
247 : : &tinfo, fcinfo->flinfo));
248 : : }
249 : :
250 : : Datum
7261 teodor@sigaev.ru 251 : 210 : gbt_date_same(PG_FUNCTION_ARGS)
252 : : {
7168 bruce@momjian.us 253 : 210 : dateKEY *b1 = (dateKEY *) PG_GETARG_POINTER(0);
254 : 210 : dateKEY *b2 = (dateKEY *) PG_GETARG_POINTER(1);
255 : 210 : bool *result = (bool *) PG_GETARG_POINTER(2);
256 : :
2581 andrew@dunslane.net 257 : 210 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
7168 bruce@momjian.us 258 : 210 : PG_RETURN_POINTER(result);
259 : : }
|