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