OSDN Git Service

contrib uninstall scripts
[pg-rex/syncrep.git] / contrib / btree_gist / btree_date.c
1 #include "btree_gist.h"
2 #include "btree_utils_num.h"
3 #include "utils/date.h"
4
5 typedef struct
6 {
7         DateADT         lower;
8         DateADT         upper;
9 }       dateKEY;
10
11 /*
12 ** date ops
13 */
14 PG_FUNCTION_INFO_V1(gbt_date_compress);
15 PG_FUNCTION_INFO_V1(gbt_date_union);
16 PG_FUNCTION_INFO_V1(gbt_date_picksplit);
17 PG_FUNCTION_INFO_V1(gbt_date_consistent);
18 PG_FUNCTION_INFO_V1(gbt_date_penalty);
19 PG_FUNCTION_INFO_V1(gbt_date_same);
20
21 Datum           gbt_date_compress(PG_FUNCTION_ARGS);
22 Datum           gbt_date_union(PG_FUNCTION_ARGS);
23 Datum           gbt_date_picksplit(PG_FUNCTION_ARGS);
24 Datum           gbt_date_consistent(PG_FUNCTION_ARGS);
25 Datum           gbt_date_penalty(PG_FUNCTION_ARGS);
26 Datum           gbt_date_same(PG_FUNCTION_ARGS);
27
28 static bool
29 gbt_dategt(const void *a, const void *b)
30 {
31         return DatumGetBool(
32                                                 DirectFunctionCall2(date_gt, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
33                 );
34 }
35
36 static bool
37 gbt_datege(const void *a, const void *b)
38 {
39         return DatumGetBool(
40                                                 DirectFunctionCall2(date_ge, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
41                 );
42 }
43
44 static bool
45 gbt_dateeq(const void *a, const void *b)
46 {
47         return DatumGetBool(
48                                                 DirectFunctionCall2(date_eq, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
49                 );
50 }
51
52 static bool
53 gbt_datele(const void *a, const void *b)
54 {
55         return DatumGetBool(
56                                                 DirectFunctionCall2(date_le, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
57                 );
58 }
59
60 static bool
61 gbt_datelt(const void *a, const void *b)
62 {
63         return DatumGetBool(
64                                                 DirectFunctionCall2(date_lt, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b)))
65                 );
66 }
67
68
69
70 static int
71 gbt_datekey_cmp(const void *a, const void *b)
72 {
73         if (gbt_dategt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
74                 return 1;
75         else if (gbt_datelt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
76                 return -1;
77         return 0;
78 }
79
80
81 static const gbtree_ninfo tinfo =
82 {
83         gbt_t_date,
84         sizeof(DateADT),
85         gbt_dategt,
86         gbt_datege,
87         gbt_dateeq,
88         gbt_datele,
89         gbt_datelt,
90         gbt_datekey_cmp
91 };
92
93
94 /**************************************************
95  * date ops
96  **************************************************/
97
98
99
100 Datum
101 gbt_date_compress(PG_FUNCTION_ARGS)
102 {
103         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
104         GISTENTRY  *retval = NULL;
105
106         PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
107 }
108
109
110
111 Datum
112 gbt_date_consistent(PG_FUNCTION_ARGS)
113 {
114         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
115         DateADT         query = PG_GETARG_DATEADT(1);
116         dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
117         GBT_NUMKEY_R key;
118         StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
119
120         key.lower = (GBT_NUMKEY *) & kkk->lower;
121         key.upper = (GBT_NUMKEY *) & kkk->upper;
122
123         PG_RETURN_BOOL(
124                                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
125                 );
126 }
127
128
129 Datum
130 gbt_date_union(PG_FUNCTION_ARGS)
131 {
132         GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
133         void       *out = palloc(sizeof(dateKEY));
134
135         *(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
136         PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
137 }
138
139
140 Datum
141 gbt_date_penalty(PG_FUNCTION_ARGS)
142 {
143         dateKEY    *origentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
144         dateKEY    *newentry = (dateKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
145         float      *result = (float *) PG_GETARG_POINTER(2);
146         int32           diff,
147                                 res;
148
149         diff = DatumGetInt32(DirectFunctionCall2(
150                                                                                          date_mi,
151                                                                                          DateADTGetDatum(newentry->upper),
152                                                                                  DateADTGetDatum(origentry->upper)));
153
154         res = Max(diff, 0);
155
156         diff = DatumGetInt32(DirectFunctionCall2(
157                                                                                          date_mi,
158                                                                                    DateADTGetDatum(origentry->lower),
159                                                                                   DateADTGetDatum(newentry->lower)));
160
161         res += Max(diff, 0);
162
163         *result = 0.0;
164
165         if (res > 0)
166         {
167                 diff = DatumGetInt32(DirectFunctionCall2(
168                                                                                                  date_mi,
169                                                                                    DateADTGetDatum(origentry->upper),
170                                                                                  DateADTGetDatum(origentry->lower)));
171                 *result += FLT_MIN;
172                 *result += (float) (res / ((double) (res + diff)));
173                 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
174         }
175
176         PG_RETURN_POINTER(result);
177 }
178
179
180 Datum
181 gbt_date_picksplit(PG_FUNCTION_ARGS)
182 {
183         PG_RETURN_POINTER(gbt_num_picksplit(
184                                                                         (GistEntryVector *) PG_GETARG_POINTER(0),
185                                                                           (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
186                                                                                 &tinfo
187                                                                                 ));
188 }
189
190 Datum
191 gbt_date_same(PG_FUNCTION_ARGS)
192 {
193         dateKEY    *b1 = (dateKEY *) PG_GETARG_POINTER(0);
194         dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
195         bool       *result = (bool *) PG_GETARG_POINTER(2);
196
197         *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
198         PG_RETURN_POINTER(result);
199 }