O ímpeto da minha pergunta é que eu esperava que o PostgreSQL se comportasse de forma consistente ao selecionar citext
colunas, independentemente de a string a ser correspondida estar ou não encapsulada em uma ou mais instâncias de lower()
(qualquer encapsulamento está além do meu controle). Isso parece não ser o caso. (Claro, é perfeitamente possível que meus testes sejam inválidos ou que eu esteja entendendo mal os conceitos fundamentais.)
Etapas para reproduzir o cenário de teste
CREATE EXTENSION IF NOT EXISTS citext;
CREATE TABLE users (id int, email citext);
INSERT INTO users(id, email) VALUES
(1, '[email protected]');
Testes
Conforme esperado ao usar o citext
tipo, a variante em minúsculas gera um resultado:
# select * from users where email = '[email protected]';
id | email
----+------------------
1 | [email protected]
(1 row)
Alterar o =
operador para like
produz um resultado:
select * from users where email like lower('[email protected]');
id | email
----+------------------
1 | [email protected]
(1 row)
Assim como o "inverso":
# select * from users where lower(email) = '[email protected]';
id | email
----+------------------
1 | [email protected]
(1 row)
Assim como envolver os dois valores em lower()
:
# select * from users where lower(email) = lower('[email protected]');
id | email
----+------------------
1 | [email protected]
(1 row)
Minha pergunta
Por que então a consulta a seguir não retorna um resultado nesta instância?
# select * from users where email = lower('[email protected]');
id | email
----+-------
(0 rows)
Essencialmente, ele chama internamente mais baixo ao comparar valores.
A palavra operativa parece ser "essencialmente"; esta declaração implica o seguinte, o que produz um resultado:
select * from users where lower(email) = lower(lower('[email protected]'));
id | email
----+------------------
1 | [email protected]
(1 row)
Isso pode estar relacionado à seguinte advertência na Limitations
seção do documento citado acima?
O comportamento de dobra de maiúsculas e minúsculas do citext depende da configuração LC_CTYPE do seu banco de dados.
# SHOW LC_CTYPE;
lc_ctype
-------------
en_US.UTF-8
(1 row)
Qualquer explicação a este respeito é muito apreciada.