segunda-feira, março 30, 2009

case-insensitive e accent-insensitive no PostgreSQL

Gosto muito do PostgreSQL. Pessoalmente é um dos bancos que menos me causa o efeito "WTF", quando estou trabalhando com ele, com uma notável exceção... não tem nenhum parâmetro nem coisa parecida para poder fazer pesquisas case-insensitive e accent-insensitive. E isso é um grande "WTF" pra qualquer um que possua acentos na língua. Procurando uma solução, encontrei esses posts aqui: http://www.laudatio.com/wordpress/2008/11/05/postgresql-83-to_ascii-utf8/ http://www.mail-archive.com/pgsql-general@postgresql.org/msg112591.html http://www.postgresonline.com/journal/index.php?/archives/9-How-to-create-an-index-based-on-a-function.html Como meu banco é UTF-8, combinei elas em uma única solução:
CREATE OR REPLACE FUNCTION to_ascii(bytea, name)
RETURNS text STRICT AS 'to_ascii_encname' LANGUAGE internal;

CREATE OR REPLACE FUNCTION norm(a_string text)
RETURNS text AS $$
  BEGIN
    RETURN lower(to_ascii(convert_to(a_string, 'latin1'), 'latin1'));
  END
$$ LANGUAGE plpgsql
E como quando fazemos isso sempre precisamos de índice, em tese podemos criar os índices assim:
CREATE INDEX norm_tabela_campo_idx
  ON tabela
  USING btree norm(campo);

Um comentário:

  1. Obrigado por compartilhar esta solução (pelo que vejo, ainda é necessária em 2011).

    Acredito que as duas funções possam ter um desempenho melhor se declaradas como IMMUTABLE (apenas julgando pelo que os DOCS dizem a respeito desse recurso)

    ResponderExcluir