~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to contrib/citext/citext.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * contrib/citext/citext.c
 
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, Oid collid);
 
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, Oid collid)
 
46
{
 
47
        char       *lcstr,
 
48
                           *rcstr;
 
49
        int32           result;
 
50
 
 
51
        lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), collid);
 
52
        rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), collid);
 
53
 
 
54
        result = varstr_cmp(lcstr, strlen(lcstr),
 
55
                                                rcstr, strlen(rcstr),
 
56
                                                collid);
 
57
 
 
58
        pfree(lcstr);
 
59
        pfree(rcstr);
 
60
 
 
61
        return result;
 
62
}
 
63
 
 
64
/*
 
65
 *              ==================
 
66
 *              INDEXING FUNCTIONS
 
67
 *              ==================
 
68
 */
 
69
 
 
70
PG_FUNCTION_INFO_V1(citext_cmp);
 
71
 
 
72
Datum
 
73
citext_cmp(PG_FUNCTION_ARGS)
 
74
{
 
75
        text       *left = PG_GETARG_TEXT_PP(0);
 
76
        text       *right = PG_GETARG_TEXT_PP(1);
 
77
        int32           result;
 
78
 
 
79
        result = citextcmp(left, right, PG_GET_COLLATION());
 
80
 
 
81
        PG_FREE_IF_COPY(left, 0);
 
82
        PG_FREE_IF_COPY(right, 1);
 
83
 
 
84
        PG_RETURN_INT32(result);
 
85
}
 
86
 
 
87
PG_FUNCTION_INFO_V1(citext_hash);
 
88
 
 
89
Datum
 
90
citext_hash(PG_FUNCTION_ARGS)
 
91
{
 
92
        text       *txt = PG_GETARG_TEXT_PP(0);
 
93
        char       *str;
 
94
        Datum           result;
 
95
 
 
96
        str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), PG_GET_COLLATION());
 
97
        result = hash_any((unsigned char *) str, strlen(str));
 
98
        pfree(str);
 
99
 
 
100
        /* Avoid leaking memory for toasted inputs */
 
101
        PG_FREE_IF_COPY(txt, 0);
 
102
 
 
103
        PG_RETURN_DATUM(result);
 
104
}
 
105
 
 
106
/*
 
107
 *              ==================
 
108
 *              OPERATOR FUNCTIONS
 
109
 *              ==================
 
110
 */
 
111
 
 
112
PG_FUNCTION_INFO_V1(citext_eq);
 
113
 
 
114
Datum
 
115
citext_eq(PG_FUNCTION_ARGS)
 
116
{
 
117
        text       *left = PG_GETARG_TEXT_PP(0);
 
118
        text       *right = PG_GETARG_TEXT_PP(1);
 
119
        char       *lcstr,
 
120
                           *rcstr;
 
121
        bool            result;
 
122
 
 
123
        /* We can't compare lengths in advance of downcasing ... */
 
124
 
 
125
        lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
 
126
        rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
 
127
 
 
128
        /*
 
129
         * Since we only care about equality or not-equality, we can avoid all the
 
130
         * expense of strcoll() here, and just do bitwise comparison.
 
131
         */
 
132
        result = (strcmp(lcstr, rcstr) == 0);
 
133
 
 
134
        pfree(lcstr);
 
135
        pfree(rcstr);
 
136
        PG_FREE_IF_COPY(left, 0);
 
137
        PG_FREE_IF_COPY(right, 1);
 
138
 
 
139
        PG_RETURN_BOOL(result);
 
140
}
 
141
 
 
142
PG_FUNCTION_INFO_V1(citext_ne);
 
143
 
 
144
Datum
 
145
citext_ne(PG_FUNCTION_ARGS)
 
146
{
 
147
        text       *left = PG_GETARG_TEXT_PP(0);
 
148
        text       *right = PG_GETARG_TEXT_PP(1);
 
149
        char       *lcstr,
 
150
                           *rcstr;
 
151
        bool            result;
 
152
 
 
153
        /* We can't compare lengths in advance of downcasing ... */
 
154
 
 
155
        lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
 
156
        rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
 
157
 
 
158
        /*
 
159
         * Since we only care about equality or not-equality, we can avoid all the
 
160
         * expense of strcoll() here, and just do bitwise comparison.
 
161
         */
 
162
        result = (strcmp(lcstr, rcstr) != 0);
 
163
 
 
164
        pfree(lcstr);
 
165
        pfree(rcstr);
 
166
        PG_FREE_IF_COPY(left, 0);
 
167
        PG_FREE_IF_COPY(right, 1);
 
168
 
 
169
        PG_RETURN_BOOL(result);
 
170
}
 
171
 
 
172
PG_FUNCTION_INFO_V1(citext_lt);
 
173
 
 
174
Datum
 
175
citext_lt(PG_FUNCTION_ARGS)
 
176
{
 
177
        text       *left = PG_GETARG_TEXT_PP(0);
 
178
        text       *right = PG_GETARG_TEXT_PP(1);
 
179
        bool            result;
 
180
 
 
181
        result = citextcmp(left, right, PG_GET_COLLATION()) < 0;
 
182
 
 
183
        PG_FREE_IF_COPY(left, 0);
 
184
        PG_FREE_IF_COPY(right, 1);
 
185
 
 
186
        PG_RETURN_BOOL(result);
 
187
}
 
188
 
 
189
PG_FUNCTION_INFO_V1(citext_le);
 
190
 
 
191
Datum
 
192
citext_le(PG_FUNCTION_ARGS)
 
193
{
 
194
        text       *left = PG_GETARG_TEXT_PP(0);
 
195
        text       *right = PG_GETARG_TEXT_PP(1);
 
196
        bool            result;
 
197
 
 
198
        result = citextcmp(left, right, PG_GET_COLLATION()) <= 0;
 
199
 
 
200
        PG_FREE_IF_COPY(left, 0);
 
201
        PG_FREE_IF_COPY(right, 1);
 
202
 
 
203
        PG_RETURN_BOOL(result);
 
204
}
 
205
 
 
206
PG_FUNCTION_INFO_V1(citext_gt);
 
207
 
 
208
Datum
 
209
citext_gt(PG_FUNCTION_ARGS)
 
210
{
 
211
        text       *left = PG_GETARG_TEXT_PP(0);
 
212
        text       *right = PG_GETARG_TEXT_PP(1);
 
213
        bool            result;
 
214
 
 
215
        result = citextcmp(left, right, PG_GET_COLLATION()) > 0;
 
216
 
 
217
        PG_FREE_IF_COPY(left, 0);
 
218
        PG_FREE_IF_COPY(right, 1);
 
219
 
 
220
        PG_RETURN_BOOL(result);
 
221
}
 
222
 
 
223
PG_FUNCTION_INFO_V1(citext_ge);
 
224
 
 
225
Datum
 
226
citext_ge(PG_FUNCTION_ARGS)
 
227
{
 
228
        text       *left = PG_GETARG_TEXT_PP(0);
 
229
        text       *right = PG_GETARG_TEXT_PP(1);
 
230
        bool            result;
 
231
 
 
232
        result = citextcmp(left, right, PG_GET_COLLATION()) >= 0;
 
233
 
 
234
        PG_FREE_IF_COPY(left, 0);
 
235
        PG_FREE_IF_COPY(right, 1);
 
236
 
 
237
        PG_RETURN_BOOL(result);
 
238
}
 
239
 
 
240
/*
 
241
 *              ===================
 
242
 *              AGGREGATE FUNCTIONS
 
243
 *              ===================
 
244
 */
 
245
 
 
246
PG_FUNCTION_INFO_V1(citext_smaller);
 
247
 
 
248
Datum
 
249
citext_smaller(PG_FUNCTION_ARGS)
 
250
{
 
251
        text       *left = PG_GETARG_TEXT_PP(0);
 
252
        text       *right = PG_GETARG_TEXT_PP(1);
 
253
        text       *result;
 
254
 
 
255
        result = citextcmp(left, right, PG_GET_COLLATION()) < 0 ? left : right;
 
256
        PG_RETURN_TEXT_P(result);
 
257
}
 
258
 
 
259
PG_FUNCTION_INFO_V1(citext_larger);
 
260
 
 
261
Datum
 
262
citext_larger(PG_FUNCTION_ARGS)
 
263
{
 
264
        text       *left = PG_GETARG_TEXT_PP(0);
 
265
        text       *right = PG_GETARG_TEXT_PP(1);
 
266
        text       *result;
 
267
 
 
268
        result = citextcmp(left, right, PG_GET_COLLATION()) > 0 ? left : right;
 
269
        PG_RETURN_TEXT_P(result);
 
270
}