PostgreSQL

Sintaxe no PostgreSQL: booleanos

Se você não leu, recomendo que veja o artigo sobre estrutura léxica do PostgreSQL antes de começar por aqui.

Toda informática é baseada na lógica booleana. Os dados booleanos são utilizados geralmente como flags para marcar se determinado atributo de uma tabela está presente ou não. Por incrível que pareça, apesar de ser o tipo de dado mais simples que existe e fazer parte do padrão SQL, poucos SGDBs implementam este tipo de dado e armazenem ele como uma coluna de uma tabela.

Uma coluna booleana pode ter apenas 3 valores distintos, falso, verdadeiro ou nulo. O PostgreSQL possui 3 palavras reservadas para lidar com estes valores: FALSE, TRUE e NULL. Veja como exemplo a tabela verdade envolvendo valores booleanos:

Note que como resultado o PostgreSQL exibe uma representação dos valores de TRUE, FALSE e NULL como ‘f’, ‘t’ e vazio respectivamente, mas isso é apenas uma representação. Existem outras formas representar verdadeiro e falso:

Você não pode exagerar muito, se você colocar qualquer número sem aspas simples, o PostgreSQL sempre vai interpretar isso como um número. E NULL só pode ser representado com a sua palavra reservada. Não pode estar entre aspas simples e vazio é diferente de nulo. Você não pode inserir ” como sinônimo para NULL.

O PostgreSQL aceita coisas como ‘t’, ‘true’, ‘y’, ‘yes’, ‘on’, ‘1’ como sinônimos para TRUE. Mas isso funciona dentro de um INSERT. Neste contexto o PostgreSQL faz uma coerção implícita para o tipo correto de dados. Vejamos o que ocorre em outros contextos:

So far, so good. Mas existe um contexto que é mais sensível: a chamada de uma função. Suponhamos que você tenha uma função como esta:

Agora vamos chamar esta função:

Perfeito. Tudo tranquilo. Parece que o PostgreSQL está se comportando exatamente como você esperava. Então onde está o problema? Bom, acontece que no PostgreSQL você pode ter sobrecarga de funções. Ou seja, varias funções com o mesmo nome, recebendo parâmetros diferentes.  Vejamos um exemplo:

A função tem o mesmo nome, mas recebe parâmetros do tipo TEXT. Vejamos o que acontece quando fazemos exatamente a mesma chamada que antes:

Aqui o comportamento foi diferente. E veja que utilizamos exatamente a mesma chamada que antes! O PostgreSQL utilizou a função com parâmetros do tipo TEXT e não do tipo BOOLEAN. Para corrigir isso você tem duas opções:

OU seja: ou você utiliza uma coerção explícita (que você vai utilizar muito com outros tipos de dados em chamadas de funções) ou utiliza as palavras reservadas. Particularmente eu acho que utilizar sempre as palavras reservadas TRUE e FALSE muito mais elegante e evita possíveis dores de cabeça no futuro. Você pode perder um bom tempo até descobrir que existe outra função com o mesmo nome mas parâmetros diferentes…

Existe ainda um contexto peculiar em que valores booleanos podem ser utilizados de forma peculiar. Quando você quer fazer um teste do tipo verdadeiro ou falso, como num IF ou num WHERE, você pode utilizar uma sintaxe mais direta. Veja o UPDATE abaixo com o WHERE escrito de duas formas diferentes:

Observação importante

Por último um pequeno comentário sobre o uso de booleanos como tipo de dados em suas tabelas. O PostgreSQL aloca um byte e não um bit para armazenar uma coluna do tipo booleano. Em muitos casos você pode utilizar outros tipos de dados no lugar do BOOLEAN, como um TIMESTAMP (que ocupa 8 bytes) por exemplo. Diferente de tempos passados, economizar demais em tipos de dados não é uma grande vantagem. Mas imagine o caso em que você quer um flag para saber se um cliente está inativo ou não. Se você utilizar um TIMESTAMP, você pode deixar a coluna como NULL se o cliente não estiver inativo e inserir a data de inativação caso o cliente tenha sido inativado. Se uma minoria dos clientes forem inativados, o consumo de espaço em disco a mais será mínimo e você está armazenando mais informação neste caso. Saber a data de inativação pode ser importante para você no futuro. Existem outros casos em que ativo e inativo pode não ser suficientes, você pode querer ter mais valores possíveis para a sua coluna. Neste caso você poderia utilizar o tipo ENUM.

 

Leave a Reply

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.