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