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 6 : PG_FUNCTION_INFO_V1(gbt_text_compress);
14 4 : PG_FUNCTION_INFO_V1(gbt_bpchar_compress);
15 7 : PG_FUNCTION_INFO_V1(gbt_text_union);
16 7 : PG_FUNCTION_INFO_V1(gbt_text_picksplit);
17 6 : PG_FUNCTION_INFO_V1(gbt_text_consistent);
18 4 : PG_FUNCTION_INFO_V1(gbt_bpchar_consistent);
19 7 : PG_FUNCTION_INFO_V1(gbt_text_penalty);
20 7 : PG_FUNCTION_INFO_V1(gbt_text_same);
21 6 : PG_FUNCTION_INFO_V1(gbt_text_sortsupport);
22 4 : PG_FUNCTION_INFO_V1(gbt_bpchar_sortsupport);
23 :
24 :
25 : /* define for comparison */
26 :
27 : static bool
28 1234 : gbt_textgt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
29 : {
30 1234 : return DatumGetBool(DirectFunctionCall2Coll(text_gt,
31 : collation,
32 : PointerGetDatum(a),
33 : PointerGetDatum(b)));
34 : }
35 :
36 : static bool
37 1263 : gbt_textge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
38 : {
39 1263 : return DatumGetBool(DirectFunctionCall2Coll(text_ge,
40 : collation,
41 : PointerGetDatum(a),
42 : PointerGetDatum(b)));
43 : }
44 :
45 : static bool
46 381 : gbt_texteq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
47 : {
48 381 : return DatumGetBool(DirectFunctionCall2Coll(texteq,
49 : collation,
50 : PointerGetDatum(a),
51 : PointerGetDatum(b)));
52 : }
53 :
54 : static bool
55 1112 : gbt_textle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
56 : {
57 1112 : return DatumGetBool(DirectFunctionCall2Coll(text_le,
58 : collation,
59 : PointerGetDatum(a),
60 : PointerGetDatum(b)));
61 : }
62 :
63 : static bool
64 989 : gbt_textlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
65 : {
66 989 : return DatumGetBool(DirectFunctionCall2Coll(text_lt,
67 : collation,
68 : PointerGetDatum(a),
69 : PointerGetDatum(b)));
70 : }
71 :
72 : static int32
73 28465 : gbt_textcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
74 : {
75 28465 : return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
76 : collation,
77 : PointerGetDatum(a),
78 : 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 624 : gbt_bpchargt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
99 : {
100 624 : return DatumGetBool(DirectFunctionCall2Coll(bpchargt,
101 : collation,
102 : PointerGetDatum(a),
103 : PointerGetDatum(b)));
104 : }
105 :
106 : static bool
107 661 : gbt_bpcharge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
108 : {
109 661 : return DatumGetBool(DirectFunctionCall2Coll(bpcharge,
110 : collation,
111 : PointerGetDatum(a),
112 : PointerGetDatum(b)));
113 : }
114 :
115 : static bool
116 156 : gbt_bpchareq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
117 : {
118 156 : return DatumGetBool(DirectFunctionCall2Coll(bpchareq,
119 : collation,
120 : PointerGetDatum(a),
121 : PointerGetDatum(b)));
122 : }
123 :
124 : static bool
125 676 : gbt_bpcharle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
126 : {
127 676 : return DatumGetBool(DirectFunctionCall2Coll(bpcharle,
128 : collation,
129 : PointerGetDatum(a),
130 : PointerGetDatum(b)));
131 : }
132 :
133 : static bool
134 520 : gbt_bpcharlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
135 : {
136 520 : return DatumGetBool(DirectFunctionCall2Coll(bpcharlt,
137 : collation,
138 : PointerGetDatum(a),
139 : PointerGetDatum(b)));
140 : }
141 :
142 : static int32
143 57 : gbt_bpcharcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
144 : {
145 57 : return DatumGetInt32(DirectFunctionCall2Coll(bpcharcmp,
146 : collation,
147 : PointerGetDatum(a),
148 : 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 2989 : gbt_text_compress(PG_FUNCTION_ARGS)
172 : {
173 2989 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
174 :
175 2989 : if (tinfo.eml == 0)
176 : {
177 4 : tinfo.eml = pg_database_encoding_max_length();
178 : }
179 :
180 2989 : PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
181 : }
182 :
183 : Datum
184 996 : gbt_bpchar_compress(PG_FUNCTION_ARGS)
185 : {
186 : /* This should never have been distinct from gbt_text_compress */
187 996 : return gbt_text_compress(fcinfo);
188 : }
189 :
190 : Datum
191 5050 : gbt_text_consistent(PG_FUNCTION_ARGS)
192 : {
193 5050 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
194 5050 : void *query = DatumGetTextP(PG_GETARG_DATUM(1));
195 5050 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
196 : #ifdef NOT_USED
197 : Oid subtype = PG_GETARG_OID(3);
198 : #endif
199 5050 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
200 : bool retval;
201 5050 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
202 5050 : GBT_VARKEY_R r = gbt_var_key_readable(key);
203 :
204 : /* All cases served by this function are exact */
205 5050 : *recheck = false;
206 :
207 5050 : if (tinfo.eml == 0)
208 : {
209 0 : tinfo.eml = pg_database_encoding_max_length();
210 : }
211 :
212 10100 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
213 5050 : GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
214 :
215 5050 : PG_RETURN_BOOL(retval);
216 : }
217 :
218 : Datum
219 2690 : gbt_bpchar_consistent(PG_FUNCTION_ARGS)
220 : {
221 2690 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
222 2690 : void *query = DatumGetTextP(PG_GETARG_DATUM(1));
223 2690 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
224 : #ifdef NOT_USED
225 : Oid subtype = PG_GETARG_OID(3);
226 : #endif
227 2690 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
228 : bool retval;
229 2690 : GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
230 2690 : GBT_VARKEY_R r = gbt_var_key_readable(key);
231 :
232 : /* All cases served by this function are exact */
233 2690 : *recheck = false;
234 :
235 2690 : if (bptinfo.eml == 0)
236 : {
237 1 : bptinfo.eml = pg_database_encoding_max_length();
238 : }
239 :
240 5380 : retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
241 2690 : GIST_LEAF(entry), &bptinfo, fcinfo->flinfo);
242 2690 : PG_RETURN_BOOL(retval);
243 : }
244 :
245 : Datum
246 3 : gbt_text_union(PG_FUNCTION_ARGS)
247 : {
248 3 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
249 3 : int32 *size = (int *) PG_GETARG_POINTER(1);
250 :
251 3 : PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
252 : &tinfo, fcinfo->flinfo));
253 : }
254 :
255 : Datum
256 16 : gbt_text_picksplit(PG_FUNCTION_ARGS)
257 : {
258 16 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
259 16 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
260 :
261 16 : gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
262 : &tinfo, fcinfo->flinfo);
263 16 : PG_RETURN_POINTER(v);
264 : }
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 : }
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 : }
287 :
288 : static int
289 22034 : gbt_text_ssup_cmp(Datum x, Datum y, SortSupport ssup)
290 : {
291 22034 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
292 22034 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
293 :
294 22034 : GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
295 22034 : GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
296 : Datum result;
297 :
298 : /* for leaf items we expect lower == upper, so only compare lower */
299 22034 : result = DirectFunctionCall2Coll(bttextcmp,
300 : ssup->ssup_collation,
301 22034 : PointerGetDatum(arg1.lower),
302 22034 : PointerGetDatum(arg2.lower));
303 :
304 22034 : GBT_FREE_IF_COPY(key1, x);
305 22034 : GBT_FREE_IF_COPY(key2, y);
306 :
307 22034 : return DatumGetInt32(result);
308 : }
309 :
310 : Datum
311 3 : gbt_text_sortsupport(PG_FUNCTION_ARGS)
312 : {
313 3 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
314 :
315 3 : ssup->comparator = gbt_text_ssup_cmp;
316 3 : ssup->ssup_extra = NULL;
317 :
318 3 : PG_RETURN_VOID();
319 : }
320 :
321 : static int
322 11261 : gbt_bpchar_ssup_cmp(Datum x, Datum y, SortSupport ssup)
323 : {
324 11261 : GBT_VARKEY *key1 = PG_DETOAST_DATUM(x);
325 11261 : GBT_VARKEY *key2 = PG_DETOAST_DATUM(y);
326 :
327 11261 : GBT_VARKEY_R arg1 = gbt_var_key_readable(key1);
328 11261 : GBT_VARKEY_R arg2 = gbt_var_key_readable(key2);
329 : Datum result;
330 :
331 : /* for leaf items we expect lower == upper, so only compare lower */
332 11261 : result = DirectFunctionCall2Coll(bpcharcmp,
333 : ssup->ssup_collation,
334 11261 : PointerGetDatum(arg1.lower),
335 11261 : PointerGetDatum(arg2.lower));
336 :
337 11261 : GBT_FREE_IF_COPY(key1, x);
338 11261 : GBT_FREE_IF_COPY(key2, y);
339 :
340 11261 : return DatumGetInt32(result);
341 : }
342 :
343 : Datum
344 1 : gbt_bpchar_sortsupport(PG_FUNCTION_ARGS)
345 : {
346 1 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
347 :
348 1 : ssup->comparator = gbt_bpchar_ssup_cmp;
349 1 : ssup->ssup_extra = NULL;
350 :
351 1 : PG_RETURN_VOID();
352 : }
|