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 "utils/builtins.h"
9
10 /*
11 ** Text ops
12 */
13 PG_FUNCTION_INFO_V1(gbt_text_compress);
14 PG_FUNCTION_INFO_V1(gbt_bpchar_compress);
15 PG_FUNCTION_INFO_V1(gbt_text_union);
16 PG_FUNCTION_INFO_V1(gbt_text_picksplit);
17 PG_FUNCTION_INFO_V1(gbt_text_consistent);
18 PG_FUNCTION_INFO_V1(gbt_bpchar_consistent);
19 PG_FUNCTION_INFO_V1(gbt_text_penalty);
20 PG_FUNCTION_INFO_V1(gbt_text_same);
21
22
23 /* define for comparison */
24
25 static bool
gbt_textgt(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)26 gbt_textgt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
27 {
28 return DatumGetBool(DirectFunctionCall2Coll(text_gt,
29 collation,
30 PointerGetDatum(a),
31 PointerGetDatum(b)));
32 }
33
34 static bool
gbt_textge(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)35 gbt_textge(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
36 {
37 return DatumGetBool(DirectFunctionCall2Coll(text_ge,
38 collation,
39 PointerGetDatum(a),
40 PointerGetDatum(b)));
41 }
42
43 static bool
gbt_texteq(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)44 gbt_texteq(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
45 {
46 return DatumGetBool(DirectFunctionCall2Coll(texteq,
47 collation,
48 PointerGetDatum(a),
49 PointerGetDatum(b)));
50 }
51
52 static bool
gbt_textle(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)53 gbt_textle(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
54 {
55 return DatumGetBool(DirectFunctionCall2Coll(text_le,
56 collation,
57 PointerGetDatum(a),
58 PointerGetDatum(b)));
59 }
60
61 static bool
gbt_textlt(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)62 gbt_textlt(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
63 {
64 return DatumGetBool(DirectFunctionCall2Coll(text_lt,
65 collation,
66 PointerGetDatum(a),
67 PointerGetDatum(b)));
68 }
69
70 static int32
gbt_textcmp(const void * a,const void * b,Oid collation,FmgrInfo * flinfo)71 gbt_textcmp(const void *a, const void *b, Oid collation, FmgrInfo *flinfo)
72 {
73 return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
74 collation,
75 PointerGetDatum(a),
76 PointerGetDatum(b)));
77 }
78
79 static gbtree_vinfo tinfo =
80 {
81 gbt_t_text,
82 0,
83 false,
84 gbt_textgt,
85 gbt_textge,
86 gbt_texteq,
87 gbt_textle,
88 gbt_textlt,
89 gbt_textcmp,
90 NULL
91 };
92
93
94 /**************************************************
95 * Text ops
96 **************************************************/
97
98
99 Datum
gbt_text_compress(PG_FUNCTION_ARGS)100 gbt_text_compress(PG_FUNCTION_ARGS)
101 {
102 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
103
104 if (tinfo.eml == 0)
105 {
106 tinfo.eml = pg_database_encoding_max_length();
107 }
108
109 PG_RETURN_POINTER(gbt_var_compress(entry, &tinfo));
110 }
111
112 Datum
gbt_bpchar_compress(PG_FUNCTION_ARGS)113 gbt_bpchar_compress(PG_FUNCTION_ARGS)
114 {
115 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
116 GISTENTRY *retval;
117
118 if (tinfo.eml == 0)
119 {
120 tinfo.eml = pg_database_encoding_max_length();
121 }
122
123 if (entry->leafkey)
124 {
125
126 Datum d = DirectFunctionCall1(rtrim1, entry->key);
127 GISTENTRY trim;
128
129 gistentryinit(trim, d,
130 entry->rel, entry->page,
131 entry->offset, true);
132 retval = gbt_var_compress(&trim, &tinfo);
133 }
134 else
135 retval = entry;
136
137 PG_RETURN_POINTER(retval);
138 }
139
140
141
142 Datum
gbt_text_consistent(PG_FUNCTION_ARGS)143 gbt_text_consistent(PG_FUNCTION_ARGS)
144 {
145 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
146 void *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
147 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
148
149 /* Oid subtype = PG_GETARG_OID(3); */
150 bool *recheck = (bool *) PG_GETARG_POINTER(4);
151 bool retval;
152 GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
153 GBT_VARKEY_R r = gbt_var_key_readable(key);
154
155 /* All cases served by this function are exact */
156 *recheck = false;
157
158 if (tinfo.eml == 0)
159 {
160 tinfo.eml = pg_database_encoding_max_length();
161 }
162
163 retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
164 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
165
166 PG_RETURN_BOOL(retval);
167 }
168
169
170 Datum
gbt_bpchar_consistent(PG_FUNCTION_ARGS)171 gbt_bpchar_consistent(PG_FUNCTION_ARGS)
172 {
173 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
174 void *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
175 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
176
177 /* Oid subtype = PG_GETARG_OID(3); */
178 bool *recheck = (bool *) PG_GETARG_POINTER(4);
179 bool retval;
180 GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
181 GBT_VARKEY_R r = gbt_var_key_readable(key);
182 void *trim = (void *) DatumGetPointer(DirectFunctionCall1(rtrim1, PointerGetDatum(query)));
183
184 /* All cases served by this function are exact */
185 *recheck = false;
186
187 if (tinfo.eml == 0)
188 {
189 tinfo.eml = pg_database_encoding_max_length();
190 }
191
192 retval = gbt_var_consistent(&r, trim, strategy, PG_GET_COLLATION(),
193 GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
194 PG_RETURN_BOOL(retval);
195 }
196
197
198 Datum
gbt_text_union(PG_FUNCTION_ARGS)199 gbt_text_union(PG_FUNCTION_ARGS)
200 {
201 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
202 int32 *size = (int *) PG_GETARG_POINTER(1);
203
204 PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
205 &tinfo, fcinfo->flinfo));
206 }
207
208
209 Datum
gbt_text_picksplit(PG_FUNCTION_ARGS)210 gbt_text_picksplit(PG_FUNCTION_ARGS)
211 {
212 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
213 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
214
215 gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
216 &tinfo, fcinfo->flinfo);
217 PG_RETURN_POINTER(v);
218 }
219
220 Datum
gbt_text_same(PG_FUNCTION_ARGS)221 gbt_text_same(PG_FUNCTION_ARGS)
222 {
223 Datum d1 = PG_GETARG_DATUM(0);
224 Datum d2 = PG_GETARG_DATUM(1);
225 bool *result = (bool *) PG_GETARG_POINTER(2);
226
227 *result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
228 PG_RETURN_POINTER(result);
229 }
230
231
232 Datum
gbt_text_penalty(PG_FUNCTION_ARGS)233 gbt_text_penalty(PG_FUNCTION_ARGS)
234 {
235 GISTENTRY *o = (GISTENTRY *) PG_GETARG_POINTER(0);
236 GISTENTRY *n = (GISTENTRY *) PG_GETARG_POINTER(1);
237 float *result = (float *) PG_GETARG_POINTER(2);
238
239 PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
240 &tinfo, fcinfo->flinfo));
241 }
242