OSDN Git Service

Add composite-type attributes to information_schema.element_types view
[pg-rex/syncrep.git] / contrib / btree_gist / btree_int4.c
1 /*
2  * contrib/btree_gist/btree_int4.c
3  */
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6
7 typedef struct int32key
8 {
9         int32           lower;
10         int32           upper;
11 } int32KEY;
12
13 /*
14 ** int32 ops
15 */
16 PG_FUNCTION_INFO_V1(gbt_int4_compress);
17 PG_FUNCTION_INFO_V1(gbt_int4_union);
18 PG_FUNCTION_INFO_V1(gbt_int4_picksplit);
19 PG_FUNCTION_INFO_V1(gbt_int4_consistent);
20 PG_FUNCTION_INFO_V1(gbt_int4_distance);
21 PG_FUNCTION_INFO_V1(gbt_int4_penalty);
22 PG_FUNCTION_INFO_V1(gbt_int4_same);
23
24 Datum           gbt_int4_compress(PG_FUNCTION_ARGS);
25 Datum           gbt_int4_union(PG_FUNCTION_ARGS);
26 Datum           gbt_int4_picksplit(PG_FUNCTION_ARGS);
27 Datum           gbt_int4_consistent(PG_FUNCTION_ARGS);
28 Datum           gbt_int4_distance(PG_FUNCTION_ARGS);
29 Datum           gbt_int4_penalty(PG_FUNCTION_ARGS);
30 Datum           gbt_int4_same(PG_FUNCTION_ARGS);
31
32
33 static bool
34 gbt_int4gt(const void *a, const void *b)
35 {
36         return (*((int32 *) a) > *((int32 *) b));
37 }
38 static bool
39 gbt_int4ge(const void *a, const void *b)
40 {
41         return (*((int32 *) a) >= *((int32 *) b));
42 }
43 static bool
44 gbt_int4eq(const void *a, const void *b)
45 {
46         return (*((int32 *) a) == *((int32 *) b));
47 }
48 static bool
49 gbt_int4le(const void *a, const void *b)
50 {
51         return (*((int32 *) a) <= *((int32 *) b));
52 }
53 static bool
54 gbt_int4lt(const void *a, const void *b)
55 {
56         return (*((int32 *) a) < *((int32 *) b));
57 }
58
59 static int
60 gbt_int4key_cmp(const void *a, const void *b)
61 {
62         int32KEY   *ia = (int32KEY *) (((Nsrt *) a)->t);
63         int32KEY   *ib = (int32KEY *) (((Nsrt *) b)->t);
64
65         if (ia->lower == ib->lower)
66         {
67                 if (ia->upper == ib->upper)
68                         return 0;
69
70                 return (ia->upper > ib->upper) ? 1 : -1;
71         }
72
73         return (ia->lower > ib->lower) ? 1 : -1;
74 }
75
76 static float8
77 gbt_int4_dist(const void *a, const void *b)
78 {
79         return GET_FLOAT_DISTANCE(int4, a, b);
80 }
81
82
83 static const gbtree_ninfo tinfo =
84 {
85         gbt_t_int4,
86         sizeof(int32),
87         gbt_int4gt,
88         gbt_int4ge,
89         gbt_int4eq,
90         gbt_int4le,
91         gbt_int4lt,
92         gbt_int4key_cmp,
93         gbt_int4_dist
94 };
95
96
97 PG_FUNCTION_INFO_V1(int4_dist);
98 Datum           int4_dist(PG_FUNCTION_ARGS);
99 Datum
100 int4_dist(PG_FUNCTION_ARGS)
101 {
102         int4            a = PG_GETARG_INT32(0);
103         int4            b = PG_GETARG_INT32(1);
104         int4            r;
105         int4            ra;
106
107         r = a - b;
108         ra = Abs(r);
109
110         /* Overflow check. */
111         if (ra < 0 || (!SAMESIGN(a, b) && !SAMESIGN(r, a)))
112                 ereport(ERROR,
113                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
114                                  errmsg("integer out of range")));
115
116         PG_RETURN_INT32(ra);
117 }
118
119
120 /**************************************************
121  * int32 ops
122  **************************************************/
123
124
125 Datum
126 gbt_int4_compress(PG_FUNCTION_ARGS)
127 {
128         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
129         GISTENTRY  *retval = NULL;
130
131         PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
132 }
133
134
135 Datum
136 gbt_int4_consistent(PG_FUNCTION_ARGS)
137 {
138         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
139         int32           query = PG_GETARG_INT32(1);
140         StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
141
142         /* Oid          subtype = PG_GETARG_OID(3); */
143         bool       *recheck = (bool *) PG_GETARG_POINTER(4);
144         int32KEY   *kkk = (int32KEY *) DatumGetPointer(entry->key);
145         GBT_NUMKEY_R key;
146
147         /* All cases served by this function are exact */
148         *recheck = false;
149
150         key.lower = (GBT_NUMKEY *) &kkk->lower;
151         key.upper = (GBT_NUMKEY *) &kkk->upper;
152
153         PG_RETURN_BOOL(
154                                    gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
155                 );
156 }
157
158
159 Datum
160 gbt_int4_distance(PG_FUNCTION_ARGS)
161 {
162         GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
163         int32           query = PG_GETARG_INT32(1);
164
165         /* Oid          subtype = PG_GETARG_OID(3); */
166         int32KEY   *kkk = (int32KEY *) DatumGetPointer(entry->key);
167         GBT_NUMKEY_R key;
168
169         key.lower = (GBT_NUMKEY *) &kkk->lower;
170         key.upper = (GBT_NUMKEY *) &kkk->upper;
171
172         PG_RETURN_FLOAT8(
173                         gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
174                 );
175 }
176
177
178 Datum
179 gbt_int4_union(PG_FUNCTION_ARGS)
180 {
181         GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
182         void       *out = palloc(sizeof(int32KEY));
183
184         *(int *) PG_GETARG_POINTER(1) = sizeof(int32KEY);
185         PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
186 }
187
188
189 Datum
190 gbt_int4_penalty(PG_FUNCTION_ARGS)
191 {
192         int32KEY   *origentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
193         int32KEY   *newentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
194         float      *result = (float *) PG_GETARG_POINTER(2);
195
196         penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
197
198         PG_RETURN_POINTER(result);
199 }
200
201 Datum
202 gbt_int4_picksplit(PG_FUNCTION_ARGS)
203 {
204         PG_RETURN_POINTER(gbt_num_picksplit(
205                                                                         (GistEntryVector *) PG_GETARG_POINTER(0),
206                                                                           (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
207                                                                                 &tinfo
208                                                                                 ));
209 }
210
211 Datum
212 gbt_int4_same(PG_FUNCTION_ARGS)
213 {
214         int32KEY   *b1 = (int32KEY *) PG_GETARG_POINTER(0);
215         int32KEY   *b2 = (int32KEY *) PG_GETARG_POINTER(1);
216         bool       *result = (bool *) PG_GETARG_POINTER(2);
217
218         *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
219         PG_RETURN_POINTER(result);
220 }