PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
citext.c
Go to the documentation of this file.
1 /*
2  * contrib/citext/citext.c
3  */
4 #include "postgres.h"
5 
6 #include "access/hash.h"
7 #include "catalog/pg_collation.h"
8 #include "utils/builtins.h"
9 #include "utils/formatting.h"
10 #include "utils/varlena.h"
11 
12 #ifdef PG_MODULE_MAGIC
14 #endif
15 
16 /*
17  * ====================
18  * FORWARD DECLARATIONS
19  * ====================
20  */
21 
22 static int32 citextcmp(text *left, text *right, Oid collid);
23 
24 /*
25  * =================
26  * UTILITY FUNCTIONS
27  * =================
28  */
29 
30 /*
31  * citextcmp()
32  * Internal comparison function for citext strings.
33  * Returns int32 negative, zero, or positive.
34  */
35 static int32
36 citextcmp(text *left, text *right, Oid collid)
37 {
38  char *lcstr,
39  *rcstr;
40  int32 result;
41 
42  /*
43  * We must do our str_tolower calls with DEFAULT_COLLATION_OID, not the
44  * input collation as you might expect. This is so that the behavior of
45  * citext's equality and hashing functions is not collation-dependent. We
46  * should change this once the core infrastructure is able to cope with
47  * collation-dependent equality and hashing functions.
48  */
49 
52 
53  result = varstr_cmp(lcstr, strlen(lcstr),
54  rcstr, strlen(rcstr),
55  collid);
56 
57  pfree(lcstr);
58  pfree(rcstr);
59 
60  return result;
61 }
62 
63 /*
64  * ==================
65  * INDEXING FUNCTIONS
66  * ==================
67  */
68 
70 
71 Datum
73 {
74  text *left = PG_GETARG_TEXT_PP(0);
75  text *right = PG_GETARG_TEXT_PP(1);
76  int32 result;
77 
78  result = citextcmp(left, right, PG_GET_COLLATION());
79 
80  PG_FREE_IF_COPY(left, 0);
81  PG_FREE_IF_COPY(right, 1);
82 
83  PG_RETURN_INT32(result);
84 }
85 
87 
88 Datum
90 {
91  text *txt = PG_GETARG_TEXT_PP(0);
92  char *str;
93  Datum result;
94 
96  result = hash_any((unsigned char *) str, strlen(str));
97  pfree(str);
98 
99  /* Avoid leaking memory for toasted inputs */
100  PG_FREE_IF_COPY(txt, 0);
101 
102  PG_RETURN_DATUM(result);
103 }
104 
105 /*
106  * ==================
107  * OPERATOR FUNCTIONS
108  * ==================
109  */
110 
112 
113 Datum
115 {
116  text *left = PG_GETARG_TEXT_PP(0);
117  text *right = PG_GETARG_TEXT_PP(1);
118  char *lcstr,
119  *rcstr;
120  bool result;
121 
122  /* We can't compare lengths in advance of downcasing ... */
123 
126 
127  /*
128  * Since we only care about equality or not-equality, we can avoid all the
129  * expense of strcoll() here, and just do bitwise comparison.
130  */
131  result = (strcmp(lcstr, rcstr) == 0);
132 
133  pfree(lcstr);
134  pfree(rcstr);
135  PG_FREE_IF_COPY(left, 0);
136  PG_FREE_IF_COPY(right, 1);
137 
138  PG_RETURN_BOOL(result);
139 }
140 
142 
143 Datum
145 {
146  text *left = PG_GETARG_TEXT_PP(0);
147  text *right = PG_GETARG_TEXT_PP(1);
148  char *lcstr,
149  *rcstr;
150  bool result;
151 
152  /* We can't compare lengths in advance of downcasing ... */
153 
156 
157  /*
158  * Since we only care about equality or not-equality, we can avoid all the
159  * expense of strcoll() here, and just do bitwise comparison.
160  */
161  result = (strcmp(lcstr, rcstr) != 0);
162 
163  pfree(lcstr);
164  pfree(rcstr);
165  PG_FREE_IF_COPY(left, 0);
166  PG_FREE_IF_COPY(right, 1);
167 
168  PG_RETURN_BOOL(result);
169 }
170 
172 
173 Datum
175 {
176  text *left = PG_GETARG_TEXT_PP(0);
177  text *right = PG_GETARG_TEXT_PP(1);
178  bool result;
179 
180  result = citextcmp(left, right, PG_GET_COLLATION()) < 0;
181 
182  PG_FREE_IF_COPY(left, 0);
183  PG_FREE_IF_COPY(right, 1);
184 
185  PG_RETURN_BOOL(result);
186 }
187 
189 
190 Datum
192 {
193  text *left = PG_GETARG_TEXT_PP(0);
194  text *right = PG_GETARG_TEXT_PP(1);
195  bool result;
196 
197  result = citextcmp(left, right, PG_GET_COLLATION()) <= 0;
198 
199  PG_FREE_IF_COPY(left, 0);
200  PG_FREE_IF_COPY(right, 1);
201 
202  PG_RETURN_BOOL(result);
203 }
204 
206 
207 Datum
209 {
210  text *left = PG_GETARG_TEXT_PP(0);
211  text *right = PG_GETARG_TEXT_PP(1);
212  bool result;
213 
214  result = citextcmp(left, right, PG_GET_COLLATION()) > 0;
215 
216  PG_FREE_IF_COPY(left, 0);
217  PG_FREE_IF_COPY(right, 1);
218 
219  PG_RETURN_BOOL(result);
220 }
221 
223 
224 Datum
226 {
227  text *left = PG_GETARG_TEXT_PP(0);
228  text *right = PG_GETARG_TEXT_PP(1);
229  bool result;
230 
231  result = citextcmp(left, right, PG_GET_COLLATION()) >= 0;
232 
233  PG_FREE_IF_COPY(left, 0);
234  PG_FREE_IF_COPY(right, 1);
235 
236  PG_RETURN_BOOL(result);
237 }
238 
239 /*
240  * ===================
241  * AGGREGATE FUNCTIONS
242  * ===================
243  */
244 
246 
247 Datum
249 {
250  text *left = PG_GETARG_TEXT_PP(0);
251  text *right = PG_GETARG_TEXT_PP(1);
252  text *result;
253 
254  result = citextcmp(left, right, PG_GET_COLLATION()) < 0 ? left : right;
255  PG_RETURN_TEXT_P(result);
256 }
257 
259 
260 Datum
262 {
263  text *left = PG_GETARG_TEXT_PP(0);
264  text *right = PG_GETARG_TEXT_PP(1);
265  text *result;
266 
267  result = citextcmp(left, right, PG_GET_COLLATION()) > 0 ? left : right;
268  PG_RETURN_TEXT_P(result);
269 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
Datum citext_smaller(PG_FUNCTION_ARGS)
Definition: citext.c:248
char * str_tolower(const char *buff, size_t nbytes, Oid collid)
Definition: formatting.c:1509
PG_FUNCTION_INFO_V1(citext_cmp)
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
static int32 citextcmp(text *left, text *right, Oid collid)
Definition: citext.c:36
return result
Definition: formatting.c:1618
Datum citext_hash(PG_FUNCTION_ARGS)
Definition: citext.c:89
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:163
Datum citext_ge(PG_FUNCTION_ARGS)
Definition: citext.c:225
signed int int32
Definition: c.h:256
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
void pfree(void *pointer)
Definition: mcxt.c:950
Datum citext_larger(PG_FUNCTION_ARGS)
Definition: citext.c:261
Datum citext_cmp(PG_FUNCTION_ARGS)
Definition: citext.c:72
PG_MODULE_MAGIC
Definition: citext.c:13
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
Datum citext_gt(PG_FUNCTION_ARGS)
Definition: citext.c:208
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
Datum hash_any(register const unsigned char *k, register int keylen)
Definition: hashfunc.c:307
int varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid)
Definition: varlena.c:1382
Datum citext_ne(PG_FUNCTION_ARGS)
Definition: citext.c:144
Datum citext_le(PG_FUNCTION_ARGS)
Definition: citext.c:191
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Datum citext_eq(PG_FUNCTION_ARGS)
Definition: citext.c:114
Datum citext_lt(PG_FUNCTION_ARGS)
Definition: citext.c:174
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:439
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158