F.7. citext

Модуль citext предоставляет тип данных для строк, нечувствительных к регистру, citext. По сути он сравнивает значения, вызывая внутри себя функцию lower. В остальном он почти не отличается от типа text.

F.7.1. Обоснование

Стандартный способ выполнить сравнение строк без учёта регистра в PostgreSQL заключается в использовании функции lower при сравнении значений, например

SELECT * FROM tab WHERE lower(col) = LOWER(?);

Этот подход работает довольно хорошо, но имеет ряд недостатков:

Тип данных citext позволяет исключить вызовы lower в SQL-запросах и позволяет сделать первичный ключ регистронезависимым. Тип citext учитывает локаль, так же, как и тип text, что означает, что сравнение символов в верхнем и нижнем регистре зависит от правил LC_CTYPE для базы данных. Это поведение, опять же, не отличается от вызовов lower в запросах. Но так как оно реализуется прозрачно типом данных, в самих запросах дополнительно не нужно ничего делать.

F.7.2. Как его использовать

Простой пример использования:

CREATE TABLE users (
    nick CITEXT PRIMARY KEY,
    pass TEXT   NOT NULL
);

INSERT INTO users VALUES ( 'larry',  md5(random()::text) );
INSERT INTO users VALUES ( 'Tom',    md5(random()::text) );
INSERT INTO users VALUES ( 'Damian', md5(random()::text) );
INSERT INTO users VALUES ( 'NEAL',   md5(random()::text) );
INSERT INTO users VALUES ( 'Bjørn',  md5(random()::text) );

SELECT * FROM users WHERE nick = 'Larry';

Оператор SELECT вернёт один кортеж, несмотря на то, что в столбец nick записано значение larry, а в запросе фигурирует Larry.

F.7.3. Поведение при сравнении строк

Модуль citext выполняет сравнения, приводя каждую строку к нижнему регистру (как если бы вызывалась функция lower) и затем производя сравнения как обычно. Так, например, две строки будут считаться равными, если функция lower, обработав их, выдаст одинаковые результаты.

Чтобы имитировать правило сортировки без учёта регистра в максимально возможной степени, этот модуль предоставляет специальные, ориентированные на citext, операторы и функции для обработки строки. Так, например, операторы регулярных выражений ~ и ~* действуют в том же ключе, когда применяются к типу citext: оба они не учитывают регистр. Это же распространяется на операторы !~ и !~*, а также операторы LIKE ~~, ~~*, !~~ и !~~*. Если же вы хотите, чтобы эти операторы учитывали регистр, вы можете привести их аргументы к типу text.

Подобным образом, все следующие функции выполняют сопоставления без учёта регистра, если их аргументы имеют тип citext:

Для функций с регулярными выражениями, если вам нужно регистрозависимое сопоставление, вы можете добавить флаг "c", чтобы принудительно включить этот режим. Чтобы получить регистрозависимое поведение без этого флага, вы должны привести аргумент к типу text, прежде чем вызывать эту функцию.

F.7.4. Ограничения

F.7.5. Автор

Дэвид Е. Уилер

Разработку вдохновил оригинальный модуль citext Дональда Фрейзера.