1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Per-column collation support

This adds collation support for columns and domains, a COLLATE clause
to override it per expression, and B-tree index support.

Peter Eisentraut
reviewed by Pavel Stehule, Itagaki Takahiro, Robert Haas, Noah Misch
This commit is contained in:
Peter Eisentraut
2011-02-08 23:04:18 +02:00
parent 1703f0e8da
commit 414c5a2ea6
156 changed files with 4519 additions and 582 deletions

View File

@ -18,7 +18,7 @@ PG_MODULE_MAGIC;
* ====================
*/
static int32 citextcmp(text *left, text *right);
static int32 citextcmp(text *left, text *right, Oid collid);
extern Datum citext_cmp(PG_FUNCTION_ARGS);
extern Datum citext_hash(PG_FUNCTION_ARGS);
extern Datum citext_eq(PG_FUNCTION_ARGS);
@ -42,17 +42,18 @@ extern Datum citext_larger(PG_FUNCTION_ARGS);
* Returns int32 negative, zero, or positive.
*/
static int32
citextcmp(text *left, text *right)
citextcmp(text *left, text *right, Oid collid)
{
char *lcstr,
*rcstr;
int32 result;
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), collid);
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), collid);
result = varstr_cmp(lcstr, strlen(lcstr),
rcstr, strlen(rcstr));
rcstr, strlen(rcstr),
collid);
pfree(lcstr);
pfree(rcstr);
@ -75,7 +76,7 @@ citext_cmp(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
int32 result;
result = citextcmp(left, right);
result = citextcmp(left, right, PG_GET_COLLATION());
PG_FREE_IF_COPY(left, 0);
PG_FREE_IF_COPY(right, 1);
@ -92,7 +93,7 @@ citext_hash(PG_FUNCTION_ARGS)
char *str;
Datum result;
str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt));
str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), PG_GET_COLLATION());
result = hash_any((unsigned char *) str, strlen(str));
pfree(str);
@ -121,8 +122,8 @@ citext_eq(PG_FUNCTION_ARGS)
/* We can't compare lengths in advance of downcasing ... */
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
/*
* Since we only care about equality or not-equality, we can avoid all the
@ -151,8 +152,8 @@ citext_ne(PG_FUNCTION_ARGS)
/* We can't compare lengths in advance of downcasing ... */
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));
lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), PG_GET_COLLATION());
rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), PG_GET_COLLATION());
/*
* Since we only care about equality or not-equality, we can avoid all the
@ -177,7 +178,7 @@ citext_lt(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
bool result;
result = citextcmp(left, right) < 0;
result = citextcmp(left, right, PG_GET_COLLATION()) < 0;
PG_FREE_IF_COPY(left, 0);
PG_FREE_IF_COPY(right, 1);
@ -194,7 +195,7 @@ citext_le(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
bool result;
result = citextcmp(left, right) <= 0;
result = citextcmp(left, right, PG_GET_COLLATION()) <= 0;
PG_FREE_IF_COPY(left, 0);
PG_FREE_IF_COPY(right, 1);
@ -211,7 +212,7 @@ citext_gt(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
bool result;
result = citextcmp(left, right) > 0;
result = citextcmp(left, right, PG_GET_COLLATION()) > 0;
PG_FREE_IF_COPY(left, 0);
PG_FREE_IF_COPY(right, 1);
@ -228,7 +229,7 @@ citext_ge(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
bool result;
result = citextcmp(left, right) >= 0;
result = citextcmp(left, right, PG_GET_COLLATION()) >= 0;
PG_FREE_IF_COPY(left, 0);
PG_FREE_IF_COPY(right, 1);
@ -251,7 +252,7 @@ citext_smaller(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
text *result;
result = citextcmp(left, right) < 0 ? left : right;
result = citextcmp(left, right, PG_GET_COLLATION()) < 0 ? left : right;
PG_RETURN_TEXT_P(result);
}
@ -264,6 +265,6 @@ citext_larger(PG_FUNCTION_ARGS)
text *right = PG_GETARG_TEXT_PP(1);
text *result;
result = citextcmp(left, right) > 0 ? left : right;
result = citextcmp(left, right, PG_GET_COLLATION()) > 0 ? left : right;
PG_RETURN_TEXT_P(result);
}

View File

@ -52,7 +52,8 @@ CREATE TYPE citext (
STORAGE = extended,
-- make it a non-preferred member of string type category
CATEGORY = 'S',
PREFERRED = false
PREFERRED = false,
COLLATABLE = true
);
--