Line data Source code
1 : /*
2 : * contrib/btree_gist/btree_oid.c
3 : */
4 : #include "postgres.h"
5 :
6 : #include "btree_gist.h"
7 : #include "btree_utils_num.h"
8 : #include "utils/sortsupport.h"
9 :
10 : typedef struct
11 : {
12 : Oid lower;
13 : Oid upper;
14 : } oidKEY;
15 :
16 : /* GiST support functions */
17 4 : PG_FUNCTION_INFO_V1(gbt_oid_compress);
18 4 : PG_FUNCTION_INFO_V1(gbt_oid_fetch);
19 4 : PG_FUNCTION_INFO_V1(gbt_oid_union);
20 4 : PG_FUNCTION_INFO_V1(gbt_oid_picksplit);
21 4 : PG_FUNCTION_INFO_V1(gbt_oid_consistent);
22 4 : PG_FUNCTION_INFO_V1(gbt_oid_distance);
23 4 : PG_FUNCTION_INFO_V1(gbt_oid_penalty);
24 4 : PG_FUNCTION_INFO_V1(gbt_oid_same);
25 4 : PG_FUNCTION_INFO_V1(gbt_oid_sortsupport);
26 :
27 :
28 : static bool
29 4488 : gbt_oidgt(const void *a, const void *b, FmgrInfo *flinfo)
30 : {
31 4488 : return (*((const Oid *) a) > *((const Oid *) b));
32 : }
33 : static bool
34 516 : gbt_oidge(const void *a, const void *b, FmgrInfo *flinfo)
35 : {
36 516 : return (*((const Oid *) a) >= *((const Oid *) b));
37 : }
38 : static bool
39 500 : gbt_oideq(const void *a, const void *b, FmgrInfo *flinfo)
40 : {
41 500 : return (*((const Oid *) a) == *((const Oid *) b));
42 : }
43 : static bool
44 2026 : gbt_oidle(const void *a, const void *b, FmgrInfo *flinfo)
45 : {
46 2026 : return (*((const Oid *) a) <= *((const Oid *) b));
47 : }
48 : static bool
49 5988 : gbt_oidlt(const void *a, const void *b, FmgrInfo *flinfo)
50 : {
51 5988 : return (*((const Oid *) a) < *((const Oid *) b));
52 : }
53 :
54 : static int
55 3994 : gbt_oidkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
56 : {
57 3994 : oidKEY *ia = (oidKEY *) (((const Nsrt *) a)->t);
58 3994 : oidKEY *ib = (oidKEY *) (((const Nsrt *) b)->t);
59 :
60 3994 : if (ia->lower == ib->lower)
61 : {
62 0 : if (ia->upper == ib->upper)
63 0 : return 0;
64 :
65 0 : return (ia->upper > ib->upper) ? 1 : -1;
66 : }
67 :
68 3994 : return (ia->lower > ib->lower) ? 1 : -1;
69 : }
70 :
71 : static float8
72 0 : gbt_oid_dist(const void *a, const void *b, FmgrInfo *flinfo)
73 : {
74 0 : Oid aa = *(const Oid *) a;
75 0 : Oid bb = *(const Oid *) b;
76 :
77 0 : if (aa < bb)
78 0 : return (float8) (bb - aa);
79 : else
80 0 : return (float8) (aa - bb);
81 : }
82 :
83 :
84 : static const gbtree_ninfo tinfo =
85 : {
86 : gbt_t_oid,
87 : sizeof(Oid),
88 : 8, /* sizeof(gbtreekey8) */
89 : gbt_oidgt,
90 : gbt_oidge,
91 : gbt_oideq,
92 : gbt_oidle,
93 : gbt_oidlt,
94 : gbt_oidkey_cmp,
95 : gbt_oid_dist
96 : };
97 :
98 :
99 2 : PG_FUNCTION_INFO_V1(oid_dist);
100 : Datum
101 0 : oid_dist(PG_FUNCTION_ARGS)
102 : {
103 0 : Oid a = PG_GETARG_OID(0);
104 0 : Oid b = PG_GETARG_OID(1);
105 : Oid res;
106 :
107 0 : if (a < b)
108 0 : res = b - a;
109 : else
110 0 : res = a - b;
111 0 : PG_RETURN_OID(res);
112 : }
113 :
114 :
115 : /**************************************************
116 : * GiST support functions
117 : **************************************************/
118 :
119 : Datum
120 2008 : gbt_oid_compress(PG_FUNCTION_ARGS)
121 : {
122 2008 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
123 :
124 2008 : PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
125 : }
126 :
127 : Datum
128 0 : gbt_oid_fetch(PG_FUNCTION_ARGS)
129 : {
130 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
131 :
132 0 : PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
133 : }
134 :
135 : Datum
136 5540 : gbt_oid_consistent(PG_FUNCTION_ARGS)
137 : {
138 5540 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
139 5540 : Oid query = PG_GETARG_OID(1);
140 5540 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
141 :
142 : /* Oid subtype = PG_GETARG_OID(3); */
143 5540 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
144 5540 : oidKEY *kkk = (oidKEY *) DatumGetPointer(entry->key);
145 : GBT_NUMKEY_R key;
146 :
147 : /* All cases served by this function are exact */
148 5540 : *recheck = false;
149 :
150 5540 : key.lower = (GBT_NUMKEY *) &kkk->lower;
151 5540 : key.upper = (GBT_NUMKEY *) &kkk->upper;
152 :
153 5540 : PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
154 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
155 : }
156 :
157 : Datum
158 0 : gbt_oid_distance(PG_FUNCTION_ARGS)
159 : {
160 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
161 0 : Oid query = PG_GETARG_OID(1);
162 :
163 : /* Oid subtype = PG_GETARG_OID(3); */
164 0 : oidKEY *kkk = (oidKEY *) DatumGetPointer(entry->key);
165 : GBT_NUMKEY_R key;
166 :
167 0 : key.lower = (GBT_NUMKEY *) &kkk->lower;
168 0 : key.upper = (GBT_NUMKEY *) &kkk->upper;
169 :
170 0 : PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
171 : &tinfo, fcinfo->flinfo));
172 : }
173 :
174 : Datum
175 0 : gbt_oid_union(PG_FUNCTION_ARGS)
176 : {
177 0 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
178 0 : void *out = palloc(sizeof(oidKEY));
179 :
180 0 : *(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
181 0 : PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
182 : }
183 :
184 : Datum
185 0 : gbt_oid_penalty(PG_FUNCTION_ARGS)
186 : {
187 0 : oidKEY *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
188 0 : oidKEY *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
189 0 : float *result = (float *) PG_GETARG_POINTER(2);
190 :
191 0 : penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
192 :
193 0 : PG_RETURN_POINTER(result);
194 : }
195 :
196 : Datum
197 6 : gbt_oid_picksplit(PG_FUNCTION_ARGS)
198 : {
199 6 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
200 : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
201 : &tinfo, fcinfo->flinfo));
202 : }
203 :
204 : Datum
205 0 : gbt_oid_same(PG_FUNCTION_ARGS)
206 : {
207 0 : oidKEY *b1 = (oidKEY *) PG_GETARG_POINTER(0);
208 0 : oidKEY *b2 = (oidKEY *) PG_GETARG_POINTER(1);
209 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
210 :
211 0 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
212 0 : PG_RETURN_POINTER(result);
213 : }
214 :
215 : static int
216 1998 : gbt_oid_ssup_cmp(Datum x, Datum y, SortSupport ssup)
217 : {
218 1998 : oidKEY *arg1 = (oidKEY *) DatumGetPointer(x);
219 1998 : oidKEY *arg2 = (oidKEY *) DatumGetPointer(y);
220 :
221 : /* for leaf items we expect lower == upper, so only compare lower */
222 1998 : if (arg1->lower > arg2->lower)
223 0 : return 1;
224 1998 : else if (arg1->lower < arg2->lower)
225 1998 : return -1;
226 : else
227 0 : return 0;
228 : }
229 :
230 : Datum
231 2 : gbt_oid_sortsupport(PG_FUNCTION_ARGS)
232 : {
233 2 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
234 :
235 2 : ssup->comparator = gbt_oid_ssup_cmp;
236 2 : ssup->ssup_extra = NULL;
237 :
238 2 : PG_RETURN_VOID();
239 : }
|