Line data Source code
1 : /*
2 : * contrib/btree_gist/btree_text.c
3 : */
4 : #include "postgres.h"
5 :
6 : #include "btree_gist.h"
7 : #include "btree_utils_var.h"
8 : #include "mb/pg_wchar.h"
9 : #include "utils/fmgrprotos.h"
10 : #include "utils/sortsupport.h"
11 :
12 : /* GiST support functions */
13 0 : PG_FUNCTION_INFO_V1(gbt_text_compress);
14 0 : PG_FUNCTION_INFO_V1(gbt_bpchar_compress);
15 0 : PG_FUNCTION_INFO_V1(gbt_text_union);
16 0 : PG_FUNCTION_INFO_V1(gbt_text_picksplit);
17 0 : PG_FUNCTION_INFO_V1(gbt_text_consistent);
18 0 : PG_FUNCTION_INFO_V1(gbt_bpchar_consistent);
19 0 : PG_FUNCTION_INFO_V1(gbt_text_penalty);
20 0 : PG_FUNCTION_INFO_V1(gbt_text_same);
21 0 : PG_FUNCTION_INFO_V1(gbt_text_sortsupport);
22 0 : PG_FUNCTION_INFO_V1(gbt_bpchar_sortsupport);
23 :
24 :
25 : /* define for comparison */
26 :
27 : static bool
28 0 : gbt_textgt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
29 : {
30 0 : return DatumGetBool(DirectFunctionCall2Coll(text_gt,
31 0 : collation,
32 0 : PointerGetDatum(a),
33 0 : PointerGetDatum(b)));
34 : }
35 :
36 : static bool
37 0 : gbt_textge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
38 : {
39 0 : return DatumGetBool(DirectFunctionCall2Coll(text_ge,
40 0 : collation,
41 0 : PointerGetDatum(a),
42 0 : PointerGetDatum(b)));
43 : }
44 :
45 : static bool
46 0 : gbt_texteq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
47 : {
48 0 : return DatumGetBool(DirectFunctionCall2Coll(texteq,
49 0 : collation,
50 0 : PointerGetDatum(a),
51 0 : PointerGetDatum(b)));
52 : }
53 :
54 : static bool
55 0 : gbt_textle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
56 : {
57 0 : return DatumGetBool(DirectFunctionCall2Coll(text_le,
58 0 : collation,
59 0 : PointerGetDatum(a),
60 0 : PointerGetDatum(b)));
61 : }
62 :
63 : static bool
64 0 : gbt_textlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
65 : {
66 0 : return DatumGetBool(DirectFunctionCall2Coll(text_lt,
67 0 : collation,
68 0 : PointerGetDatum(a),
69 0 : PointerGetDatum(b)));
70 : }
71 :
72 : static int32
73 0 : gbt_textcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
74 : {
75 0 : return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
76 0 : collation,
77 0 : PointerGetDatum(a),
78 0 : PointerGetDatum(b)));
79 : }
80 :
81 : static gbtree_vinfo tinfo =
82 : {
83 : gbt_t_text,
84 : 0,
85 : false,
86 : gbt_textgt,
87 : gbt_textge,
88 : gbt_texteq,
89 : gbt_textle,
90 : gbt_textlt,
91 : gbt_textcmp,
92 : NULL
93 : };
94 :
95 : /* bpchar needs its own comparison rules */
96 :
97 : static bool
98 0 : gbt_bpchargt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
99 : {
100 0 : return DatumGetBool(DirectFunctionCall2Coll(bpchargt,
101 0 : collation,
102 0 : PointerGetDatum(a),
103 0 : PointerGetDatum(b)));
104 : }
105 :
106 : static bool
107 0 : gbt_bpcharge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
108 : {
109 0 : return DatumGetBool(DirectFunctionCall2Coll(bpcharge,
110 0 : collation,
111 0 : PointerGetDatum(a),
112 0 : PointerGetDatum(b)));
113 : }
114 :
115 : static bool
116 0 : gbt_bpchareq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
117 : {
118 0 : return DatumGetBool(DirectFunctionCall2Coll(bpchareq,
119 0 : collation,
120 0 : PointerGetDatum(a),
121 0 : PointerGetDatum(b)));
122 : }
123 :
124 : static bool
125 0 : gbt_bpcharle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
126 : {
127 0 : return DatumGetBool(DirectFunctionCall2Coll(bpcharle,
128 0 : collation,
129 0 : PointerGetDatum(a),
130 0 : PointerGetDatum(b)));
131 : }
132 :
133 : static bool
134 0 : gbt_bpcharlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
135 : {
136 0 : return DatumGetBool(DirectFunctionCall2Coll(bpcharlt,
137 0 : collation,
138 0 : PointerGetDatum(a),
139 0 : PointerGetDatum(b)));
140 : }
141 :
142 : static int32
143 0 : gbt_bpcharcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
144 : {
145 0 : return DatumGetInt32(DirectFunctionCall2Coll(bpcharcmp,
146 0 : collation,
147 0 : PointerGetDatum(a),
148 0 : PointerGetDatum(b)));
149 : }
150 :
151 : static gbtree_vinfo bptinfo =
152 : {
153 : gbt_t_bpchar,
154 : 0,
155 : false,
156 : gbt_bpchargt,
157 : gbt_bpcharge,
158 : gbt_bpchareq,
159 : gbt_bpcharle,
160 : gbt_bpcharlt,
161 : gbt_bpcharcmp,
162 : NULL
163 : };
164 :
165 :
166 : /**************************************************
167 : * GiST support functions
168 : **************************************************/
169 :
170 : Datum
171 0 : gbt_text_compress(PG_FUNCTION_ARGS)
172 : {
173 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
174 :
175 0 : if (tinfo.eml == 0)
176 : {
177 0 : tinfo.eml = pg_database_encoding_max_length();
178 0 : }
179 :
180 0 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
181 0 : }
182 :
183 : Datum
184 0 : gbt_bpchar_compress(PG_FUNCTION_ARGS)
185 : {
186 : /* This should never have been distinct from gbt_text_compress */
187 0 : return gbt_text_compress(fcinfo);
188 : }
189 :
190 : Datum
191 0 : gbt_text_consistent(PG_FUNCTION_ARGS)
192 : {
193 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
194 0 : void *query = DatumGetTextP(PG_GETARG_DATUM(1));
195 0 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
196 : #ifdef NOT_USED
197 : Oid subtype = PG_GETARG_OID(3);
198 : #endif
199 0 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
200 0 : bool retval;
201 0 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
202 0 : GBT_VARKEY_R r = gbt_var_key_readable(key);
203 :
204 : /* All cases served by this function are exact */
205 0 : *recheck = false;
206 :
207 0 : if (tinfo.eml == 0)
208 : {
209 0 : tinfo.eml = pg_database_encoding_max_length();
210 0 : }
211 :
212 0 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
213 0 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
214 :
215 0 : PG_RETURN_BOOL(retval);
216 0 : }
217 :
218 : Datum
219 0 : gbt_bpchar_consistent(PG_FUNCTION_ARGS)
220 : {
221 0 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
222 0 : void *query = DatumGetTextP(PG_GETARG_DATUM(1));
223 0 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
224 : #ifdef NOT_USED
225 : Oid subtype = PG_GETARG_OID(3);
226 : #endif
227 0 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
228 0 : bool retval;
229 0 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
230 0 : GBT_VARKEY_R r = gbt_var_key_readable(key);
231 :
232 : /* All cases served by this function are exact */
233 0 : *recheck = false;
234 :
235 0 : if (bptinfo.eml == 0)
236 : {
237 0 : bptinfo.eml = pg_database_encoding_max_length();
238 0 : }
239 :
240 0 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
241 0 : GIST_LEAF(entry), &bptinfo, fcinfo->flinfo);
242 0 : PG_RETURN_BOOL(retval);
243 0 : }
244 :
245 : Datum
246 0 : gbt_text_union(PG_FUNCTION_ARGS)
247 : {
248 0 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
249 0 : int32 *size = (int *) PG_GETARG_POINTER(1);
250 :
251 0 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
252 : &tinfo, fcinfo->flinfo));
253 0 : }
254 :
255 : Datum
256 0 : gbt_text_picksplit(PG_FUNCTION_ARGS)
257 : {
258 0 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
259 0 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
260 :
261 0 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
262 0 : &tinfo, fcinfo->flinfo);
263 0 : PG_RETURN_POINTER(v);
264 0 : }
265 :
266 : Datum
267 0 : gbt_text_same(PG_FUNCTION_ARGS)
268 : {
269 0 : Datum d1 = PG_GETARG_DATUM(0);
270 0 : Datum d2 = PG_GETARG_DATUM(1);
271 0 : bool *result = (bool *) PG_GETARG_POINTER(2);
272 :
273 0 : *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
274 0 : PG_RETURN_POINTER(result);
275 0 : }
276 :
277 : Datum
278 0 : gbt_text_penalty(PG_FUNCTION_ARGS)
279 : {
280 0 : GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
281 0 : GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
282 0 : float *result = (float *) PG_GETARG_POINTER(2);
283 :
284 0 : PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
285 : &tinfo, fcinfo->flinfo));
286 0 : }
287 :
288 : static int
289 0 : gbt_text_ssup_cmp(Datum x, Datum y, SortSupport ssup)
290 : {
291 0 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
292 0 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
293 :
294 0 : GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
295 0 : GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
296 0 : Datum result;
297 :
298 : /* for leaf items we expect lower == upper, so only compare lower */
299 0 : result = DirectFunctionCall2Coll(bttextcmp,
300 0 : ssup->ssup_collation,
301 0 : PointerGetDatum(arg1.lower),
302 0 : PointerGetDatum(arg2.lower));
303 :
304 0 : GBT_FREE_IF_COPY(key1, x);
305 0 : GBT_FREE_IF_COPY(key2, y);
306 :
307 0 : return DatumGetInt32(result);
308 0 : }
309 :
310 : Datum
311 0 : gbt_text_sortsupport(PG_FUNCTION_ARGS)
312 : {
313 0 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
314 :
315 0 : ssup->comparator = gbt_text_ssup_cmp;
316 0 : ssup->ssup_extra = NULL;
317 :
318 0 : PG_RETURN_VOID();
319 0 : }
320 :
321 : static int
322 0 : gbt_bpchar_ssup_cmp(Datum x, Datum y, SortSupport ssup)
323 : {
324 0 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
325 0 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
326 :
327 0 : GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
328 0 : GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
329 0 : Datum result;
330 :
331 : /* for leaf items we expect lower == upper, so only compare lower */
332 0 : result = DirectFunctionCall2Coll(bpcharcmp,
333 0 : ssup->ssup_collation,
334 0 : PointerGetDatum(arg1.lower),
335 0 : PointerGetDatum(arg2.lower));
336 :
337 0 : GBT_FREE_IF_COPY(key1, x);
338 0 : GBT_FREE_IF_COPY(key2, y);
339 :
340 0 : return DatumGetInt32(result);
341 0 : }
342 :
343 : Datum
344 0 : gbt_bpchar_sortsupport(PG_FUNCTION_ARGS)
345 : {
346 0 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
347 :
348 0 : ssup->comparator = gbt_bpchar_ssup_cmp;
349 0 : ssup->ssup_extra = NULL;
350 :
351 0 : PG_RETURN_VOID();
352 0 : }
|