Content-Length: 909578 | pFad | http://github.com/tonybelloni/postgres/commit/ab9907f5e5eba6e4e17a279d07a1a9df21ec5b19

96 Add a new, improved version of citext as a contrib module. · tonybelloni/postgres@ab9907f · GitHub
Skip to content

Commit ab9907f

Browse files
committed
Add a new, improved version of citext as a contrib module.
David E. Wheeler
1 parent 6fe8796 commit ab9907f

File tree

11 files changed

+2517
-3
lines changed

11 files changed

+2517
-3
lines changed

contrib/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $PostgreSQL: pgsql/contrib/Makefile,v 1.83 2008/05/08 16:49:36 tgl Exp $
1+
# $PostgreSQL: pgsql/contrib/Makefile,v 1.84 2008/07/29 18:31:20 tgl Exp $
22

33
subdir = contrib
44
top_builddir = ..
@@ -8,6 +8,7 @@ WANTED_DIRS = \
88
adminpack \
99
btree_gist \
1010
chkpass \
11+
citext \
1112
cube \
1213
dblink \
1314
dict_int \

contrib/README

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ chkpass -
3636
An auto-encrypted password datatype
3737
by D'Arcy J.M. Cain <darcy@druid.net>
3838

39+
citext -
40+
A case-insensitive character string datatype
41+
by David E. Wheeler <david@kineticode.com>
42+
3943
cube -
4044
Multidimensional-cube datatype (GiST indexing example)
4145
by Gene Selkov, Jr. <selkovjr@mcs.anl.gov>

contrib/citext/Makefile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# $PostgreSQL: pgsql/contrib/citext/Makefile,v 1.1 2008/07/29 18:31:20 tgl Exp $
2+
3+
MODULES = citext
4+
DATA_built = citext.sql
5+
DATA = uninstall_citext.sql
6+
REGRESS = citext
7+
8+
ifdef USE_PGXS
9+
PG_CONFIG = pg_config
10+
PGXS := $(shell $(PG_CONFIG) --pgxs)
11+
include $(PGXS)
12+
else
13+
subdir = contrib/citext
14+
top_builddir = ../..
15+
include $(top_builddir)/src/Makefile.global
16+
include $(top_srcdir)/contrib/contrib-global.mk
17+
endif

contrib/citext/citext.c

+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
* $PostgreSQL: pgsql/contrib/citext/citext.c,v 1.1 2008/07/29 18:31:20 tgl Exp $
3+
*/
4+
#include "postgres.h"
5+
6+
#include "access/hash.h"
7+
#include "fmgr.h"
8+
#include "utils/builtins.h"
9+
#include "utils/formatting.h"
10+
11+
#ifdef PG_MODULE_MAGIC
12+
PG_MODULE_MAGIC;
13+
#endif
14+
15+
/*
16+
* ====================
17+
* FORWARD DECLARATIONS
18+
* ====================
19+
*/
20+
21+
static int32 citextcmp (text *left, text *right);
22+
extern Datum citext_cmp (PG_FUNCTION_ARGS);
23+
extern Datum citext_hash (PG_FUNCTION_ARGS);
24+
extern Datum citext_eq (PG_FUNCTION_ARGS);
25+
extern Datum citext_ne (PG_FUNCTION_ARGS);
26+
extern Datum citext_gt (PG_FUNCTION_ARGS);
27+
extern Datum citext_ge (PG_FUNCTION_ARGS);
28+
extern Datum citext_lt (PG_FUNCTION_ARGS);
29+
extern Datum citext_le (PG_FUNCTION_ARGS);
30+
extern Datum citext_smaller (PG_FUNCTION_ARGS);
31+
extern Datum citext_larger (PG_FUNCTION_ARGS);
32+
33+
/*
34+
* =================
35+
* UTILITY FUNCTIONS
36+
* =================
37+
*/
38+
39+
/*
40+
* citextcmp()
41+
* Internal comparison function for citext strings.
42+
* Returns int32 negative, zero, or positive.
43+
*/
44+
static int32
45+
citextcmp (text *left, text *right)
46+
{
47+
char *lcstr, *rcstr;
48+
int32 result;
49+
50+
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
51+
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
52+
53+
result = varstr_cmp(lcstr, strlen(lcstr),
54+
rcstr, strlen(rcstr));
55+
56+
pfree(lcstr);
57+
pfree(rcstr);
58+
59+
return result;
60+
}
61+
62+
/*
63+
* ==================
64+
* INDEXING FUNCTIONS
65+
* ==================
66+
*/
67+
68+
PG_FUNCTION_INFO_V1(citext_cmp);
69+
70+
Datum
71+
citext_cmp(PG_FUNCTION_ARGS)
72+
{
73+
text *left = PG_GETARG_TEXT_PP(0);
74+
text *right = PG_GETARG_TEXT_PP(1);
75+
int32 result;
76+
77+
result = citextcmp(left, right);
78+
79+
PG_FREE_IF_COPY(left, 0);
80+
PG_FREE_IF_COPY(right, 1);
81+
82+
PG_RETURN_INT32(result);
83+
}
84+
85+
PG_FUNCTION_INFO_V1(citext_hash);
86+
87+
Datum
88+
citext_hash(PG_FUNCTION_ARGS)
89+
{
90+
text *txt = PG_GETARG_TEXT_PP(0);
91+
char *str;
92+
Datum result;
93+
94+
str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt));
95+
result = hash_any((unsigned char *) str, strlen(str));
96+
pfree(str);
97+
98+
/* Avoid leaking memory for toasted inputs */
99+
PG_FREE_IF_COPY(txt, 0);
100+
101+
PG_RETURN_DATUM(result);
102+
}
103+
104+
/*
105+
* ==================
106+
* OPERATOR FUNCTIONS
107+
* ==================
108+
*/
109+
110+
PG_FUNCTION_INFO_V1(citext_eq);
111+
112+
Datum
113+
citext_eq(PG_FUNCTION_ARGS)
114+
{
115+
text *left = PG_GETARG_TEXT_PP(0);
116+
text *right = PG_GETARG_TEXT_PP(1);
117+
char *lcstr, *rcstr;
118+
bool result;
119+
120+
/* We can't compare lengths in advance of downcasing ... */
121+
122+
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
123+
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
124+
125+
/*
126+
* Since we only care about equality or not-equality, we can
127+
* avoid all the expense of strcoll() here, and just do bitwise
128+
* comparison.
129+
*/
130+
result = (strcmp(lcstr, rcstr) == 0);
131+
132+
pfree(lcstr);
133+
pfree(rcstr);
134+
PG_FREE_IF_COPY(left, 0);
135+
PG_FREE_IF_COPY(right, 1);
136+
137+
PG_RETURN_BOOL(result);
138+
}
139+
140+
PG_FUNCTION_INFO_V1(citext_ne);
141+
142+
Datum
143+
citext_ne(PG_FUNCTION_ARGS)
144+
{
145+
text *left = PG_GETARG_TEXT_PP(0);
146+
text *right = PG_GETARG_TEXT_PP(1);
147+
char *lcstr, *rcstr;
148+
bool result;
149+
150+
/* We can't compare lengths in advance of downcasing ... */
151+
152+
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
153+
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
154+
155+
/*
156+
* Since we only care about equality or not-equality, we can
157+
* avoid all the expense of strcoll() here, and just do bitwise
158+
* comparison.
159+
*/
160+
result = (strcmp(lcstr, rcstr) != 0);
161+
162+
pfree(lcstr);
163+
pfree(rcstr);
164+
PG_FREE_IF_COPY(left, 0);
165+
PG_FREE_IF_COPY(right, 1);
166+
167+
PG_RETURN_BOOL(result);
168+
}
169+
170+
PG_FUNCTION_INFO_V1(citext_lt);
171+
172+
Datum
173+
citext_lt(PG_FUNCTION_ARGS)
174+
{
175+
text *left = PG_GETARG_TEXT_PP(0);
176+
text *right = PG_GETARG_TEXT_PP(1);
177+
bool result;
178+
179+
result = citextcmp(left, right) < 0;
180+
181+
PG_FREE_IF_COPY(left, 0);
182+
PG_FREE_IF_COPY(right, 1);
183+
184+
PG_RETURN_BOOL(result);
185+
}
186+
187+
PG_FUNCTION_INFO_V1(citext_le);
188+
189+
Datum
190+
citext_le(PG_FUNCTION_ARGS)
191+
{
192+
text *left = PG_GETARG_TEXT_PP(0);
193+
text *right = PG_GETARG_TEXT_PP(1);
194+
bool result;
195+
196+
result = citextcmp(left, right) <= 0;
197+
198+
PG_FREE_IF_COPY(left, 0);
199+
PG_FREE_IF_COPY(right, 1);
200+
201+
PG_RETURN_BOOL(result);
202+
}
203+
204+
PG_FUNCTION_INFO_V1(citext_gt);
205+
206+
Datum
207+
citext_gt(PG_FUNCTION_ARGS)
208+
{
209+
text *left = PG_GETARG_TEXT_PP(0);
210+
text *right = PG_GETARG_TEXT_PP(1);
211+
bool result;
212+
213+
result = citextcmp(left, right) > 0;
214+
215+
PG_FREE_IF_COPY(left, 0);
216+
PG_FREE_IF_COPY(right, 1);
217+
218+
PG_RETURN_BOOL(result);
219+
}
220+
221+
PG_FUNCTION_INFO_V1(citext_ge);
222+
223+
Datum
224+
citext_ge(PG_FUNCTION_ARGS)
225+
{
226+
text *left = PG_GETARG_TEXT_PP(0);
227+
text *right = PG_GETARG_TEXT_PP(1);
228+
bool result;
229+
230+
result = citextcmp(left, right) >= 0;
231+
232+
PG_FREE_IF_COPY(left, 0);
233+
PG_FREE_IF_COPY(right, 1);
234+
235+
PG_RETURN_BOOL(result);
236+
}
237+
238+
/*
239+
* ===================
240+
* AGGREGATE FUNCTIONS
241+
* ===================
242+
*/
243+
244+
PG_FUNCTION_INFO_V1(citext_smaller);
245+
246+
Datum
247+
citext_smaller(PG_FUNCTION_ARGS)
248+
{
249+
text *left = PG_GETARG_TEXT_PP(0);
250+
text *right = PG_GETARG_TEXT_PP(1);
251+
text *result;
252+
253+
result = citextcmp(left, right) < 0 ? left : right;
254+
PG_RETURN_TEXT_P(result);
255+
}
256+
257+
PG_FUNCTION_INFO_V1(citext_larger);
258+
259+
Datum
260+
citext_larger(PG_FUNCTION_ARGS)
261+
{
262+
text *left = PG_GETARG_TEXT_PP(0);
263+
text *right = PG_GETARG_TEXT_PP(1);
264+
text *result;
265+
266+
result = citextcmp(left, right) > 0 ? left : right;
267+
PG_RETURN_TEXT_P(result);
268+
}

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tonybelloni/postgres/commit/ab9907f5e5eba6e4e17a279d07a1a9df21ec5b19

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy