PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
citext.c File Reference
#include "postgres.h"
#include "catalog/pg_collation.h"
#include "common/hashfn.h"
#include "fmgr.h"
#include "utils/formatting.h"
#include "utils/varlena.h"
#include "varatt.h"
Include dependency graph for citext.c:

Go to the source code of this file.

Functions

 PG_MODULE_MAGIC_EXT (.name="citext",.version=PG_VERSION)
 
static int32 citextcmp (text *left, text *right, Oid collid)
 
static int32 internal_citext_pattern_cmp (text *left, text *right, Oid collid)
 
 PG_FUNCTION_INFO_V1 (citext_cmp)
 
Datum citext_cmp (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_pattern_cmp)
 
Datum citext_pattern_cmp (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_hash)
 
Datum citext_hash (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_hash_extended)
 
Datum citext_hash_extended (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_eq)
 
Datum citext_eq (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_ne)
 
Datum citext_ne (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_lt)
 
Datum citext_lt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_le)
 
Datum citext_le (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_gt)
 
Datum citext_gt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_ge)
 
Datum citext_ge (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_pattern_lt)
 
Datum citext_pattern_lt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_pattern_le)
 
Datum citext_pattern_le (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_pattern_gt)
 
Datum citext_pattern_gt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_pattern_ge)
 
Datum citext_pattern_ge (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_smaller)
 
Datum citext_smaller (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (citext_larger)
 
Datum citext_larger (PG_FUNCTION_ARGS)
 

Function Documentation

◆ citext_cmp()

Datum citext_cmp ( PG_FUNCTION_ARGS  )

Definition at line 110 of file citext.c.

111{
112 text *left = PG_GETARG_TEXT_PP(0);
113 text *right = PG_GETARG_TEXT_PP(1);
114 int32 result;
115
116 result = citextcmp(left, right, PG_GET_COLLATION());
117
118 PG_FREE_IF_COPY(left, 0);
119 PG_FREE_IF_COPY(right, 1);
120
121 PG_RETURN_INT32(result);
122}
int32_t int32
Definition: c.h:498
static int32 citextcmp(text *left, text *right, Oid collid)
Definition: citext.c:39
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GET_COLLATION()
Definition: fmgr.h:198
Definition: c.h:658

References citextcmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_INT32.

◆ citext_eq()

Datum citext_eq ( PG_FUNCTION_ARGS  )

Definition at line 189 of file citext.c.

190{
191 text *left = PG_GETARG_TEXT_PP(0);
192 text *right = PG_GETARG_TEXT_PP(1);
193 char *lcstr,
194 *rcstr;
195 bool result;
196
197 /* We can't compare lengths in advance of downcasing ... */
198
199 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
200 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
201
202 /*
203 * Since we only care about equality or not-equality, we can avoid all the
204 * expense of strcoll() here, and just do bitwise comparison.
205 */
206 result = (strcmp(lcstr, rcstr) == 0);
207
208 pfree(lcstr);
209 pfree(rcstr);
210 PG_FREE_IF_COPY(left, 0);
211 PG_FREE_IF_COPY(right, 1);
212
213 PG_RETURN_BOOL(result);
214}
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
char * str_tolower(const char *buff, size_t nbytes, Oid collid)
Definition: formatting.c:1637
void pfree(void *pointer)
Definition: mcxt.c:2150
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

References pfree(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str_tolower(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ citext_ge()

Datum citext_ge ( PG_FUNCTION_ARGS  )

Definition at line 300 of file citext.c.

301{
302 text *left = PG_GETARG_TEXT_PP(0);
303 text *right = PG_GETARG_TEXT_PP(1);
304 bool result;
305
306 result = citextcmp(left, right, PG_GET_COLLATION()) >= 0;
307
308 PG_FREE_IF_COPY(left, 0);
309 PG_FREE_IF_COPY(right, 1);
310
311 PG_RETURN_BOOL(result);
312}

References citextcmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_gt()

Datum citext_gt ( PG_FUNCTION_ARGS  )

Definition at line 283 of file citext.c.

284{
285 text *left = PG_GETARG_TEXT_PP(0);
286 text *right = PG_GETARG_TEXT_PP(1);
287 bool result;
288
289 result = citextcmp(left, right, PG_GET_COLLATION()) > 0;
290
291 PG_FREE_IF_COPY(left, 0);
292 PG_FREE_IF_COPY(right, 1);
293
294 PG_RETURN_BOOL(result);
295}

References citextcmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_hash()

Datum citext_hash ( PG_FUNCTION_ARGS  )

Definition at line 144 of file citext.c.

145{
146 text *txt = PG_GETARG_TEXT_PP(0);
147 char *str;
148 Datum result;
149
150 str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID);
151 result = hash_any((unsigned char *) str, strlen(str));
152 pfree(str);
153
154 /* Avoid leaking memory for toasted inputs */
155 PG_FREE_IF_COPY(txt, 0);
156
157 PG_RETURN_DATUM(result);
158}
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
const char * str
uintptr_t Datum
Definition: postgres.h:69

References hash_any(), pfree(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, PG_RETURN_DATUM, str, str_tolower(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ citext_hash_extended()

Datum citext_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 163 of file citext.c.

164{
165 text *txt = PG_GETARG_TEXT_PP(0);
166 uint64 seed = PG_GETARG_INT64(1);
167 char *str;
168 Datum result;
169
170 str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID);
171 result = hash_any_extended((unsigned char *) str, strlen(str), seed);
172 pfree(str);
173
174 /* Avoid leaking memory for toasted inputs */
175 PG_FREE_IF_COPY(txt, 0);
176
177 PG_RETURN_DATUM(result);
178}
uint64_t uint64
Definition: c.h:503
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37

References hash_any_extended(), pfree(), PG_FREE_IF_COPY, PG_GETARG_INT64, PG_GETARG_TEXT_PP, PG_RETURN_DATUM, str, str_tolower(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ citext_larger()

Datum citext_larger ( PG_FUNCTION_ARGS  )

Definition at line 404 of file citext.c.

405{
406 text *left = PG_GETARG_TEXT_PP(0);
407 text *right = PG_GETARG_TEXT_PP(1);
408 text *result;
409
410 result = citextcmp(left, right, PG_GET_COLLATION()) > 0 ? left : right;
411 PG_RETURN_TEXT_P(result);
412}
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372

References citextcmp(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_TEXT_P.

◆ citext_le()

Datum citext_le ( PG_FUNCTION_ARGS  )

Definition at line 266 of file citext.c.

267{
268 text *left = PG_GETARG_TEXT_PP(0);
269 text *right = PG_GETARG_TEXT_PP(1);
270 bool result;
271
272 result = citextcmp(left, right, PG_GET_COLLATION()) <= 0;
273
274 PG_FREE_IF_COPY(left, 0);
275 PG_FREE_IF_COPY(right, 1);
276
277 PG_RETURN_BOOL(result);
278}

References citextcmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_lt()

Datum citext_lt ( PG_FUNCTION_ARGS  )

Definition at line 249 of file citext.c.

250{
251 text *left = PG_GETARG_TEXT_PP(0);
252 text *right = PG_GETARG_TEXT_PP(1);
253 bool result;
254
255 result = citextcmp(left, right, PG_GET_COLLATION()) < 0;
256
257 PG_FREE_IF_COPY(left, 0);
258 PG_FREE_IF_COPY(right, 1);
259
260 PG_RETURN_BOOL(result);
261}

References citextcmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_ne()

Datum citext_ne ( PG_FUNCTION_ARGS  )

Definition at line 219 of file citext.c.

220{
221 text *left = PG_GETARG_TEXT_PP(0);
222 text *right = PG_GETARG_TEXT_PP(1);
223 char *lcstr,
224 *rcstr;
225 bool result;
226
227 /* We can't compare lengths in advance of downcasing ... */
228
229 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
230 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
231
232 /*
233 * Since we only care about equality or not-equality, we can avoid all the
234 * expense of strcoll() here, and just do bitwise comparison.
235 */
236 result = (strcmp(lcstr, rcstr) != 0);
237
238 pfree(lcstr);
239 pfree(rcstr);
240 PG_FREE_IF_COPY(left, 0);
241 PG_FREE_IF_COPY(right, 1);
242
243 PG_RETURN_BOOL(result);
244}

References pfree(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, str_tolower(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ citext_pattern_cmp()

Datum citext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 127 of file citext.c.

128{
129 text *left = PG_GETARG_TEXT_PP(0);
130 text *right = PG_GETARG_TEXT_PP(1);
131 int32 result;
132
133 result = internal_citext_pattern_cmp(left, right, PG_GET_COLLATION());
134
135 PG_FREE_IF_COPY(left, 0);
136 PG_FREE_IF_COPY(right, 1);
137
138 PG_RETURN_INT32(result);
139}
static int32 internal_citext_pattern_cmp(text *left, text *right, Oid collid)
Definition: citext.c:72

References internal_citext_pattern_cmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_INT32.

◆ citext_pattern_ge()

Datum citext_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 368 of file citext.c.

369{
370 text *left = PG_GETARG_TEXT_PP(0);
371 text *right = PG_GETARG_TEXT_PP(1);
372 bool result;
373
374 result = internal_citext_pattern_cmp(left, right, PG_GET_COLLATION()) >= 0;
375
376 PG_FREE_IF_COPY(left, 0);
377 PG_FREE_IF_COPY(right, 1);
378
379 PG_RETURN_BOOL(result);
380}

References internal_citext_pattern_cmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_pattern_gt()

Datum citext_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 351 of file citext.c.

352{
353 text *left = PG_GETARG_TEXT_PP(0);
354 text *right = PG_GETARG_TEXT_PP(1);
355 bool result;
356
357 result = internal_citext_pattern_cmp(left, right, PG_GET_COLLATION()) > 0;
358
359 PG_FREE_IF_COPY(left, 0);
360 PG_FREE_IF_COPY(right, 1);
361
362 PG_RETURN_BOOL(result);
363}

References internal_citext_pattern_cmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_pattern_le()

Datum citext_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 334 of file citext.c.

335{
336 text *left = PG_GETARG_TEXT_PP(0);
337 text *right = PG_GETARG_TEXT_PP(1);
338 bool result;
339
340 result = internal_citext_pattern_cmp(left, right, PG_GET_COLLATION()) <= 0;
341
342 PG_FREE_IF_COPY(left, 0);
343 PG_FREE_IF_COPY(right, 1);
344
345 PG_RETURN_BOOL(result);
346}

References internal_citext_pattern_cmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_pattern_lt()

Datum citext_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 317 of file citext.c.

318{
319 text *left = PG_GETARG_TEXT_PP(0);
320 text *right = PG_GETARG_TEXT_PP(1);
321 bool result;
322
323 result = internal_citext_pattern_cmp(left, right, PG_GET_COLLATION()) < 0;
324
325 PG_FREE_IF_COPY(left, 0);
326 PG_FREE_IF_COPY(right, 1);
327
328 PG_RETURN_BOOL(result);
329}

References internal_citext_pattern_cmp(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ citext_smaller()

Datum citext_smaller ( PG_FUNCTION_ARGS  )

Definition at line 391 of file citext.c.

392{
393 text *left = PG_GETARG_TEXT_PP(0);
394 text *right = PG_GETARG_TEXT_PP(1);
395 text *result;
396
397 result = citextcmp(left, right, PG_GET_COLLATION()) < 0 ? left : right;
398 PG_RETURN_TEXT_P(result);
399}

References citextcmp(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, and PG_RETURN_TEXT_P.

◆ citextcmp()

static int32 citextcmp ( text left,
text right,
Oid  collid 
)
static

Definition at line 39 of file citext.c.

40{
41 char *lcstr,
42 *rcstr;
43 int32 result;
44
45 /*
46 * We must do our str_tolower calls with DEFAULT_COLLATION_OID, not the
47 * input collation as you might expect. This is so that the behavior of
48 * citext's equality and hashing functions is not collation-dependent. We
49 * should change this once the core infrastructure is able to cope with
50 * collation-dependent equality and hashing functions.
51 */
52
53 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
54 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
55
56 result = varstr_cmp(lcstr, strlen(lcstr),
57 rcstr, strlen(rcstr),
58 collid);
59
60 pfree(lcstr);
61 pfree(rcstr);
62
63 return result;
64}
Oid collid
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1610

References collid, pfree(), str_tolower(), VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

Referenced by citext_cmp(), citext_ge(), citext_gt(), citext_larger(), citext_le(), citext_lt(), and citext_smaller().

◆ internal_citext_pattern_cmp()

static int32 internal_citext_pattern_cmp ( text left,
text right,
Oid  collid 
)
static

Definition at line 72 of file citext.c.

73{
74 char *lcstr,
75 *rcstr;
76 int llen,
77 rlen;
78 int32 result;
79
80 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
81 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
82
83 llen = strlen(lcstr);
84 rlen = strlen(rcstr);
85
86 result = memcmp(lcstr, rcstr, Min(llen, rlen));
87 if (result == 0)
88 {
89 if (llen < rlen)
90 result = -1;
91 else if (llen > rlen)
92 result = 1;
93 }
94
95 pfree(lcstr);
96 pfree(rcstr);
97
98 return result;
99}
#define Min(x, y)
Definition: c.h:975

References Min, pfree(), str_tolower(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by citext_pattern_cmp(), citext_pattern_ge(), citext_pattern_gt(), citext_pattern_le(), and citext_pattern_lt().

◆ PG_FUNCTION_INFO_V1() [1/16]

PG_FUNCTION_INFO_V1 ( citext_cmp  )

◆ PG_FUNCTION_INFO_V1() [2/16]

PG_FUNCTION_INFO_V1 ( citext_eq  )

◆ PG_FUNCTION_INFO_V1() [3/16]

PG_FUNCTION_INFO_V1 ( citext_ge  )

◆ PG_FUNCTION_INFO_V1() [4/16]

PG_FUNCTION_INFO_V1 ( citext_gt  )

◆ PG_FUNCTION_INFO_V1() [5/16]

PG_FUNCTION_INFO_V1 ( citext_hash  )

◆ PG_FUNCTION_INFO_V1() [6/16]

PG_FUNCTION_INFO_V1 ( citext_hash_extended  )

◆ PG_FUNCTION_INFO_V1() [7/16]

PG_FUNCTION_INFO_V1 ( citext_larger  )

◆ PG_FUNCTION_INFO_V1() [8/16]

PG_FUNCTION_INFO_V1 ( citext_le  )

◆ PG_FUNCTION_INFO_V1() [9/16]

PG_FUNCTION_INFO_V1 ( citext_lt  )

◆ PG_FUNCTION_INFO_V1() [10/16]

PG_FUNCTION_INFO_V1 ( citext_ne  )

◆ PG_FUNCTION_INFO_V1() [11/16]

PG_FUNCTION_INFO_V1 ( citext_pattern_cmp  )

◆ PG_FUNCTION_INFO_V1() [12/16]

PG_FUNCTION_INFO_V1 ( citext_pattern_ge  )

◆ PG_FUNCTION_INFO_V1() [13/16]

PG_FUNCTION_INFO_V1 ( citext_pattern_gt  )

◆ PG_FUNCTION_INFO_V1() [14/16]

PG_FUNCTION_INFO_V1 ( citext_pattern_le  )

◆ PG_FUNCTION_INFO_V1() [15/16]

PG_FUNCTION_INFO_V1 ( citext_pattern_lt  )

◆ PG_FUNCTION_INFO_V1() [16/16]

PG_FUNCTION_INFO_V1 ( citext_smaller  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "citext",
version = PG_VERSION 
)