CREATE CAST (tipo_de_origem AS tipo_de_destino) WITH FUNCTION nome_da_função (tipo_do_argumento) [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (tipo_de_origem AS tipo_de_destino) WITHOUT FUNCTION [ AS ASSIGNMENT | AS IMPLICIT ]
O comando CREATE CAST cria uma conversão. A conversão especifica como realizar a conversão entre dois tipos de dado. Por exemplo,
SELECT CAST(42 AS text);
converte a constante inteira 42 para o tipo text chamando uma função especificada previamente, neste caso text(int4); se nenhuma conversão adequada tiver sido definida, a conversão falha.
Dois tipos podem ser binariamente compatíveis, significando que podem ser convertidos um no outro "livremente", sem chamar nenhuma função. Requer que os valores correspondentes utilizem a mesma representação interna. Por exemplo, os tipos text e varchar são binariamente compatíveis.
Por padrão, a conversão somente pode ser feita por uma solicitação de conversão explícita, ou seja, uma construção explícita CAST(x AS nome_do_tipo), x::nome_do_tipo, ou nome_do_tipo(x).
Se a conversão for marcada como AS ASSIGNMENT então pode ser chamada implicitamente quando for atribuído um valor a uma coluna com o tipo de dado de destino. Por exemplo, supondo que foo.f1 seja uma coluna do tipo text, então a atribuição
INSERT INTO foo (f1) VALUES (42);
é permitida se a conversão do tipo integer para o tipo text estiver marcada como AS ASSIGNMENT, senão a atribuição não é permitida; geralmente é utilizado o termo conversão de atribuição (assignment cast) para descrever este tipo de conversão.
Se a conversão estiver marcada como AS IMPLICIT então poderá ser chamada implicitamente em qualquer contexto, seja em uma atribuição ou internamente em uma expressão. Por exemplo, como || recebe operandos do tipo text, então a expressão
SELECT 'Data e hora ' || now();
somente será permitida se a conversão do tipo timestamp para o tipo text estiver marcada como AS IMPLICIT, senão será necessário escrever a conversão explicitamente como, por exemplo,
SELECT 'Data e hora ' || CAST(now() AS text);
(Geralmente é utilizado o termo conversão implícita (implicit cast) para descrever este tipo de conversão).
É sensato ser conservador com relação a marcar conversões como implícitas. Uma superabundância de possibilidades de conversões implícitas pode fazer o PostgreSQL escolher interpretações surpreendentes para os comandos, ou até não ser capaz de resolver o comando devido à existência de várias interpretações possíveis. Uma boa regra empírica é tornar a conversão chamável implicitamente somente nos casos de transformações que preservam as informações entre tipos da mesma categoria geral. Por exemplo, a conversão de int2 em int4 pode ser implícita, mas a conversão de float8 para int4 provavelmente deve ser somente de atribuição. Conversões entre tipos de categorias diferentes, como text para int4, é melhor serem somente explícitas.
É necessário ser o dono do tipo de dado de origem ou de destino para poder criar uma conversão. Para criar uma conversão binariamente compatível é necessário ser um superusuário; esta restrição existe porque uma conversão binariamente compatível pode facilmente derrubar o servidor.
Use o comando DROP CAST para remover conversões criadas pelo usuário.
Lembre-se que para ser possível converter tipos nas duas direções é necessário declarar conversões para as duas direções explicitamente.
Antes do PostgreSQL 7.3 toda função que possuía o mesmo nome de um tipo de dado, retornava este tipo de dado, e recebia um argumento de um tipo diferente era, automaticamente, uma função de conversão. Esta convenção foi abandonada devido à introdução dos esquemas e da capacidade de representar conversões binariamente compatíveis nos catálogos do sistema. As funções de conversão internas ainda seguem este esquema de nomes, mas também devem aparecer como conversões no catálogo do sistema pg_cast.
Para criar uma conversão do tipo text para o tipo int4 utilizando a função int4(text):
CREATE CAST (text AS int4) WITH FUNCTION int4(text);
(Esta conversão já está pré-definida no sistema).