00001
00002
00003
00004 #include "postgres.h"
00005
00006 #include "access/hash.h"
00007 #include "catalog/pg_collation.h"
00008 #include "utils/builtins.h"
00009 #include "utils/formatting.h"
00010
00011 #ifdef PG_MODULE_MAGIC
00012 PG_MODULE_MAGIC;
00013 #endif
00014
00015
00016
00017
00018
00019
00020
00021 static int32 citextcmp(text *left, text *right, Oid collid);
00022 extern Datum citext_cmp(PG_FUNCTION_ARGS);
00023 extern Datum citext_hash(PG_FUNCTION_ARGS);
00024 extern Datum citext_eq(PG_FUNCTION_ARGS);
00025 extern Datum citext_ne(PG_FUNCTION_ARGS);
00026 extern Datum citext_gt(PG_FUNCTION_ARGS);
00027 extern Datum citext_ge(PG_FUNCTION_ARGS);
00028 extern Datum citext_lt(PG_FUNCTION_ARGS);
00029 extern Datum citext_le(PG_FUNCTION_ARGS);
00030 extern Datum citext_smaller(PG_FUNCTION_ARGS);
00031 extern Datum citext_larger(PG_FUNCTION_ARGS);
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 static int32
00045 citextcmp(text *left, text *right, Oid collid)
00046 {
00047 char *lcstr,
00048 *rcstr;
00049 int32 result;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
00060 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
00061
00062 result = varstr_cmp(lcstr, strlen(lcstr),
00063 rcstr, strlen(rcstr),
00064 collid);
00065
00066 pfree(lcstr);
00067 pfree(rcstr);
00068
00069 return result;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 PG_FUNCTION_INFO_V1(citext_cmp);
00079
00080 Datum
00081 citext_cmp(PG_FUNCTION_ARGS)
00082 {
00083 text *left = PG_GETARG_TEXT_PP(0);
00084 text *right = PG_GETARG_TEXT_PP(1);
00085 int32 result;
00086
00087 result = citextcmp(left, right, PG_GET_COLLATION());
00088
00089 PG_FREE_IF_COPY(left, 0);
00090 PG_FREE_IF_COPY(right, 1);
00091
00092 PG_RETURN_INT32(result);
00093 }
00094
00095 PG_FUNCTION_INFO_V1(citext_hash);
00096
00097 Datum
00098 citext_hash(PG_FUNCTION_ARGS)
00099 {
00100 text *txt = PG_GETARG_TEXT_PP(0);
00101 char *str;
00102 Datum result;
00103
00104 str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID);
00105 result = hash_any((unsigned char *) str, strlen(str));
00106 pfree(str);
00107
00108
00109 PG_FREE_IF_COPY(txt, 0);
00110
00111 PG_RETURN_DATUM(result);
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 PG_FUNCTION_INFO_V1(citext_eq);
00121
00122 Datum
00123 citext_eq(PG_FUNCTION_ARGS)
00124 {
00125 text *left = PG_GETARG_TEXT_PP(0);
00126 text *right = PG_GETARG_TEXT_PP(1);
00127 char *lcstr,
00128 *rcstr;
00129 bool result;
00130
00131
00132
00133 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
00134 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
00135
00136
00137
00138
00139
00140 result = (strcmp(lcstr, rcstr) == 0);
00141
00142 pfree(lcstr);
00143 pfree(rcstr);
00144 PG_FREE_IF_COPY(left, 0);
00145 PG_FREE_IF_COPY(right, 1);
00146
00147 PG_RETURN_BOOL(result);
00148 }
00149
00150 PG_FUNCTION_INFO_V1(citext_ne);
00151
00152 Datum
00153 citext_ne(PG_FUNCTION_ARGS)
00154 {
00155 text *left = PG_GETARG_TEXT_PP(0);
00156 text *right = PG_GETARG_TEXT_PP(1);
00157 char *lcstr,
00158 *rcstr;
00159 bool result;
00160
00161
00162
00163 lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
00164 rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);
00165
00166
00167
00168
00169
00170 result = (strcmp(lcstr, rcstr) != 0);
00171
00172 pfree(lcstr);
00173 pfree(rcstr);
00174 PG_FREE_IF_COPY(left, 0);
00175 PG_FREE_IF_COPY(right, 1);
00176
00177 PG_RETURN_BOOL(result);
00178 }
00179
00180 PG_FUNCTION_INFO_V1(citext_lt);
00181
00182 Datum
00183 citext_lt(PG_FUNCTION_ARGS)
00184 {
00185 text *left = PG_GETARG_TEXT_PP(0);
00186 text *right = PG_GETARG_TEXT_PP(1);
00187 bool result;
00188
00189 result = citextcmp(left, right, PG_GET_COLLATION()) < 0;
00190
00191 PG_FREE_IF_COPY(left, 0);
00192 PG_FREE_IF_COPY(right, 1);
00193
00194 PG_RETURN_BOOL(result);
00195 }
00196
00197 PG_FUNCTION_INFO_V1(citext_le);
00198
00199 Datum
00200 citext_le(PG_FUNCTION_ARGS)
00201 {
00202 text *left = PG_GETARG_TEXT_PP(0);
00203 text *right = PG_GETARG_TEXT_PP(1);
00204 bool result;
00205
00206 result = citextcmp(left, right, PG_GET_COLLATION()) <= 0;
00207
00208 PG_FREE_IF_COPY(left, 0);
00209 PG_FREE_IF_COPY(right, 1);
00210
00211 PG_RETURN_BOOL(result);
00212 }
00213
00214 PG_FUNCTION_INFO_V1(citext_gt);
00215
00216 Datum
00217 citext_gt(PG_FUNCTION_ARGS)
00218 {
00219 text *left = PG_GETARG_TEXT_PP(0);
00220 text *right = PG_GETARG_TEXT_PP(1);
00221 bool result;
00222
00223 result = citextcmp(left, right, PG_GET_COLLATION()) > 0;
00224
00225 PG_FREE_IF_COPY(left, 0);
00226 PG_FREE_IF_COPY(right, 1);
00227
00228 PG_RETURN_BOOL(result);
00229 }
00230
00231 PG_FUNCTION_INFO_V1(citext_ge);
00232
00233 Datum
00234 citext_ge(PG_FUNCTION_ARGS)
00235 {
00236 text *left = PG_GETARG_TEXT_PP(0);
00237 text *right = PG_GETARG_TEXT_PP(1);
00238 bool result;
00239
00240 result = citextcmp(left, right, PG_GET_COLLATION()) >= 0;
00241
00242 PG_FREE_IF_COPY(left, 0);
00243 PG_FREE_IF_COPY(right, 1);
00244
00245 PG_RETURN_BOOL(result);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254 PG_FUNCTION_INFO_V1(citext_smaller);
00255
00256 Datum
00257 citext_smaller(PG_FUNCTION_ARGS)
00258 {
00259 text *left = PG_GETARG_TEXT_PP(0);
00260 text *right = PG_GETARG_TEXT_PP(1);
00261 text *result;
00262
00263 result = citextcmp(left, right, PG_GET_COLLATION()) < 0 ? left : right;
00264 PG_RETURN_TEXT_P(result);
00265 }
00266
00267 PG_FUNCTION_INFO_V1(citext_larger);
00268
00269 Datum
00270 citext_larger(PG_FUNCTION_ARGS)
00271 {
00272 text *left = PG_GETARG_TEXT_PP(0);
00273 text *right = PG_GETARG_TEXT_PP(1);
00274 text *result;
00275
00276 result = citextcmp(left, right, PG_GET_COLLATION()) > 0 ? left : right;
00277 PG_RETURN_TEXT_P(result);
00278 }