10.1. Visão geral #

A linguagem SQL é fortemente tipada, ou seja, cada item de dados tem um tipo de dados associado que determina o seu comportamento e o uso permitido. O PostgreSQL possui um sistema extensível de tipos de dados, mais geral e flexível que o encontrado em outras implementações da linguagem SQL. Portanto, a maior parte do comportamento de conversão de tipo de dados no PostgreSQL é governado por regras gerais, e não por heurísticas ad hoc. Isso permite o uso de expressões com tipos de dados diversos, mesmo com tipos de dados definidos pelo usuário.

O rastreador/analisador (scanner/parser) do PostgreSQL divide os elementos léxicos em cinco categorias fundamentais: números inteiros, números não inteiros, cadeias de caracteres, identificadores e palavras-chave. As constantes da maioria dos tipos de dados não numéricos são primeiramente classificadas como cadeia de caracteres. A definição da linguagem SQL permite especificar nomes de tipo de dados usando cadeia de caracteres, e esse mecanismo pode ser usado no PostgreSQL para iniciar o analisador no caminho correto. Por exemplo, a consulta

SELECT text 'Origin' AS "label", point '(0,0)' AS "value";

 label  | value
--------+-------
 Origin | (0,0)
(1 linha)

possui duas constantes literais, dos tipos de dados text e point. Se não for especificado o tipo de dados para um literal cadeia de caracteres, será atribuído inicialmente o tipo de dados provisório unknown, para ser resolvido em estágios posteriores, conforme descrito abaixo.

Existem quatro construções SQL fundamentais que requerem regras de conversão de tipo de dados distintas no analisador do PostgreSQL:

Chamadas de função

Grande parte do sistema de tipos de dados do PostgreSQL é construído em torno de um rico conjunto de funções. As funções podem ter um ou mais argumentos. Como o PostgreSQL permite sobrecarga (overload) de função, o nome da função sozinho não identifica unicamente a função a ser chamada; o analisador deve selecionar a função correta segundo os tipos de dados dos argumentos fornecidos.

Operadores

O PostgreSQL permite expressões com operadores de prefixo (um argumento), bem como operadores infixos (dois argumentos). Assim como as funções, os operadores podem ser sobrecarregados, de modo que existe o mesmo problema para selecionar o operador correto.

Armazenamento de valor

As instruções SQL INSERT e UPDATE colocam os resultados das expressões em uma tabela. As expressões na instrução devem corresponder, e talvez serem convertidas, para os tipos de dados das colunas de destino.

Construções UNION, CASE, e relacionadas

Como os resultados de todas as instruções SELECT de uma construção UNION devem retornar em um único conjunto de colunas, os tipos de dados dos resultados das instruções SELECT envolvidas devem corresponder e produzirem um conjunto uniforme de saída. Da mesma maneira, as expressões de resultado de uma construção CASE devem ser convertidas em um tipo de dados comum, para que a expressão CASE tenha um tipo de dados de saída conhecido. Algumas outras construções, como ARRAY[] e as funções GREATEST e LEAST, também requerem a determinação de um tipo de dados comum para várias subexpressões.

Os catálogos do sistema armazenam informações sobre quais conversões, ou casts, existem entre quais tipos de dados e como realizar estas conversões. Podem ser criadas conversões adicionais pelo usuário usando o comando CREATE CAST. (Isto é geralmente feito em conjunto com a definição de novos tipos de dados. O conjunto de conversões entre os tipos de dados nativos foi cuidadosamente elaborado, sendo melhor não alterá-lo.)

Uma heurística adicional fornecida pelo analisador permite uma melhor determinação do comportamento de conversão adequado entre grupos de tipos de dados que possuem conversões implícitas. Os tipos de dados são divididos em várias categorias de tipo básicas, incluindo boolean, numeric, string, bitstring, datetime, timespan, geometric, network e definido pelo usuário. (Para obter a lista veja a Tabela 52.65; mas observe que também é possível criar categorias de tipo de dados personalizado.) Dentro de cada categoria pode haver um ou mais tipos preferidos, que são os preferidos quando há uma escolha de tipos de dados possíveis. Com a seleção cuidadosa de tipos de dados preferidos e conversões implícitas disponíveis, é possível garantir que expressões ambíguas (aquelas com várias soluções de análise candidatas) possam ser resolvidas de uma forma útil.

Todas as regras de conversão de tipo de dados são projetadas com vários princípios em mente: