Capítulo 1. Sintaxe do SQL

Índice
1.1. Estrutura léxica
1.1.1. Identificadores e palavras chave
1.1.2. Constantes
1.1.3. Operadores
1.1.4. Caracteres especiais
1.1.5. Comentários
1.1.6. Precedência léxica
1.2. Expressões de valor
1.2.1. Referências a colunas
1.2.2. Parâmetros posicionais
1.2.3. Chamadas de operador
1.2.4. Chamadas de funções
1.2.5. Funções de agregação
1.2.6. Transformação de tipo
1.2.7. Subconsultas escalares
1.2.8. Avaliação de expressão

Este capítulo descreve a sintaxe da linguagem SQL, estabelecendo uma base para compreender os próximos capítulos que descrevem detalhadamente como os comandos SQL são utilizados para definir e modificar os dados. [1]

Aconselha-se aos usuários já familiarizados com a linguagem SQL a leitura cuidadosa deste capítulo, porque existem várias regras e conceitos implementados pelos bancos de dados SQL de forma inconsistente, ou que são específicos do PostgreSQL.

1.1. Estrutura léxica

Uma declaração SQL é formada por uma seqüência de comandos. Um comando é formado por uma seqüência de termos (tokens) terminada por um ponto-e-vírgula (";"). O fim da declaração também termina o comando. Quais termos são válidos depende da sintaxe de cada comando.

Um termo pode ser uma palavra chave, um identificador, um identificador entre aspas, um literal (ou constante), ou um caractere especial. Geralmente os termos são separados por espaço em branco (espaço, tabulação ou nova-linha), mas não precisam estar se não houver ambigüidade (normalmente isto só acontece quando um caractere especial está adjacente a um termo de outro tipo).

Além disso, comentários podem estar presentes na declaração SQL. Os comentários não são termos, na realidade são equivalentes a espaços em branco.

Abaixo está mostrada uma declaração SQL válida (sintaticamente):

SELECT * FROM MINHA_TABELA;
UPDATE MINHA_TABELA SET A = 5;
INSERT INTO MINHA_TABELA VALUES (3, 'oi cara');

Esta é uma seqüência de três comandos, um por linha (embora isto não seja requerido; pode haver mais de um comando na mesma linha, e um único comando pode ocupar várias linhas).

A sintaxe do SQL não é muito consistente em relação a quais termos identificam comandos e quais são operandos ou parâmetros. Geralmente os primeiros termos são o nome do comando. Portanto, no exemplo mostrado acima, pode-se dizer que estão presentes os comandos "SELECT", "UPDATE" e "INSERT". Entretanto, o comando UPDATE sempre requer que o termo SET apareça em uma determinada posição, e esta forma particular do INSERT também requer a presença do termo VALUES para estar completa. As regras precisas da sintaxe de cada comando estão descritas no Manual de Referência do PostgreSQL.

1.1.1. Identificadores e palavras chave

Os termos SELECT, UPDATE e VALUES mostrados no exemplo acima são exemplos de palavras chave, ou seja, palavras que possuem um significado estabelecido na linguagem SQL. Os termos MINHA_TABELA e A são exemplos de identificadores, os quais identificam nomes de tabelas, colunas e outros objetos do banco de dados, dependendo do comando onde são utilizados. Portanto, algumas vezes são simplesmente chamados de "nomes". As palavras chave e os identificadores possuem a mesma estrutura léxica, significando que não é possível saber se o termo é um identificador ou uma palavra chave sem conhecer a linguagem. A lista completa das palavras chave pode ser encontrada no Apêndice B.

Os identificadores e as palavras chave do SQL devem iniciar por uma letra (a-z e, também, letras com diacrítico - áéç... - e letras não latinas), ou o caractere sublinhado (_). Os demais caracteres de um identificador, ou da palavra chave, podem ser letras, dígitos (0-9) ou sublinhados, embora o padrão SQL não defina nenhuma palavra chave contendo dígitos, ou que comece ou termine por um caractere sublinhado.

O sistema utiliza não mais que NAMEDATALEN-1 caracteres de um identificador; nomes maiores podem ser escritos nos comandos, mas serão truncados. Por padrão NAMEDATALEN é 64 e, portanto, o comprimento máximo de um identificador é 63 (mas antes de gerar o PostgreSQL NAMEDATALEN pode ser mudado no arquivo src/include/postgres_ext.h).

Os identificadores e as palavras chave não fazem distinção entre letras maiúsculas e minúsculas. Portanto,

UPDATE MINHA_TABELA SET A = 5;

é equivalente a

uPDaTE MINHA_TABELA SeT a = 5;

Normalmente utiliza-se a convenção de escrever as palavras chave em letras maiúsculas e os nomes em letras minúsculas, como mostrado abaixo:

UPDATE minha_tabela SET a = 5;

Existe um segundo tipo de identificador: o identificador delimitado ou identificador entre aspas, formado pela colocação de uma seqüência arbitrária de caracteres entre aspas ("). Um identificador delimitado é sempre um identificador, e nunca uma palavra chave. Portanto, "select" pode ser usado para fazer referência a uma tabela ou coluna chamada "select", enquanto um select sem aspas sempre é uma palavra chave ocasionando, por isso, um erro do analisador quando usado onde um nome de tabela ou de coluna é esperado. O exemplo acima pode ser reescrito utilizando identificadores entre aspas:

UPDATE "minha_tabela" SET "a" = 5;

Um identificador entre aspas pode conter qualquer caractere que não seja a própria aspa. Para incluir uma aspa, duas aspas devem ser escritas. Esta funcionalidade permite a criação de nomes de tabelas e de colunas que não seriam possíveis de outra forma, como os contendo espaços ou e-comercial (&). O limite de comprimento ainda se aplica.

Colocar um identificador entre aspas torna diferente as letras maiúsculas das minúsculas, enquanto os nomes não envoltos por aspas são sempre convertidos para letras minúsculas. Por exemplo, os identificadores FOO, foo e "foo" são considerados o mesmo pelo PostgreSQL, mas "Foo" e "FOO" são diferentes dos três primeiros e entre si. [2]

1.1.2. Constantes

Existem três tipos de constantes com tipo implícito no PostgreSQL: cadeias de caracteres, cadeias de bits e numéricas. As constantes também podem ser especificadas com tipo explícito, o que permite uma representação mais precisa, e um tratamento mais eficiente por parte do sistema. As constantes implícitas estão descritas abaixo; as constantes explícitas são discutidas mais adiante.

1.1.2.1. Constantes do tipo cadeia de caracteres

Uma constante do tipo cadeia de caracteres no SQL é uma seqüência arbitrária de caracteres envolta por apóstrofos (') como, por exemplo, 'Esta é uma cadeia de caracteres'. O SQL permite apóstrofos dentro de uma cadeia de caracteres digitando-se dois apóstrofos adjacentes (por exemplo, 'Maria D''Almeida'). No PostgreSQL existe a alternativa de utilizar a contrabarra ("\") como caractere de escape para colocar apóstrofos dentro de cadeia de caracteres (por exemplo, 'Maria D\'Almeida').

As seqüências de escape presentes na linguagem C também são permitidas: \b para voltar apagando (backspace), \f para avanço de página, \n para nova-linha, \r para retorno do carro, \t para tabulação e \xxx, onde xxx é o número octal correspondente ao código ASCII do caractere. Qualquer outro caractere vindo após a contrabarra é interpretado literalmente. Portanto, para incluir uma contrabarra em uma constante do tipo cadeia de caracteres, devem ser escritas duas contrabarras adjacentes.

O caractere com o código zero não pode estar presente em uma constante do tipo cadeia de caracteres.

Duas constantes do tipo cadeia de caracteres separadas apenas por espaço em branco e pelo menos um caractere de nova-linha, são concatenadas e tratadas como se a cadeia de caracteres fosse uma única constante. Por exemplo:

SELECT 'foo'
'bar';

é o mesmo que

SELECT 'foobar';

mas

SELECT 'foo'      'bar';

não possui uma sintaxe válida (este comportamento, um tanto ao quanto esquisito, é especificado no padrão SQL; o PostgreSQL apenas segue o padrão).

1.1.2.2. Constantes do tipo cadeia de bits

Uma constante do tipo cadeia de bits se parece com uma constante do tipo cadeia de caracteres contendo a letra B (maiúscula ou minúscula) logo antes do apóstrofo inicial (sem espaços separando) como, por exemplo, B'1001'. Os únicos caracteres permitidos dentro de uma constante do tipo cadeia de bits são o 0 e o 1.

Como forma alternativa, uma constante do tipo cadeia de bits pode ser especificada usando a notação hexadecimal, colocando a letra X (maiúscula ou minúscula) no início como, por exemplo, X'1FF'. Esta notação é equivalente a uma constante do tipo cadeia de bits contendo quatro dígitos binários para cada dígito hexadecimal.

As duas formas de constantes do tipo cadeia de bits podem ocupar mais de uma linha, da mesma forma que uma constante do tipo cadeia de caracteres.

1.1.2.3. Constantes numéricas

As constantes numéricas são admitidas nas seguintes formas gerais:

dígitos
dígitos.[dígitos][e[+-]dígitos]
[dígitos].dígitos[e[+-]dígitos]
dígitose[+-]dígitos

onde dígitos é um ou mais dígitos decimais (0 a 9). Pelo menos um dígito deve existir antes ou depois do ponto decimal, se este for usado. Pelo menos um dígito deve existir após a marca de expoente (e), caso esteja presente. Não podem existir espaços ou outros caracteres embutidos em uma constante numérica. Observe que os sinais menos e mais que antecedem a constante não são na verdade considerados parte da constante, e sim um operador a ser aplicado à constante.

Abaixo estão mostrados alguns exemplo de constantes numéricas válidas:

42
3.5
4.
.001
5e2
1.925e-3

Uma constante numérica não contendo o ponto decimal nem o expoente é presumida, inicialmente, como sendo do tipo inteiro se seu valor for apropriado para o tipo integer (32 bits); senão é presumida como sendo do tipo inteiro longo, se seu valor for apropriado para o tipo bigint (64 bits); caso contrário, é assumida como sendo do tipo numeric. As constantes que possuem pontos decimais e/ou expoentes sempre são inicialmente presumidas como sendo do tipo numeric.

O tipo de dado atribuído inicialmente para a constante numérica é apenas o ponto de partida para o algoritmo de resolução de tipo. Na maioria dos casos a constante é automaticamente tornada do tipo mais apropriado dependendo do contexto. Quando for necessário, pode ser feito o valor numérico ser interpretado como sendo de um tipo de dado específico, definindo a transformação a ser feita. Por exemplo, pode ser feito o valor numérico ser tratado como sendo do tipo real (float4) escrevendo

REAL '1.23'  -- estilo cadeia de caracteres
1.23::REAL   -- estilo PostgreSQL (histórico)

1.1.2.4. Constantes de outros tipos

Uma constante de um tipo arbitrário pode ser declarada utilizando uma das seguintes notações:

tipo 'cadeia de caracteres'
'cadeia de caracteres'::tipo
CAST ( 'cadeia de caracteres' AS tipo )

O texto da cadeia de caracteres é passado para a rotina de conversão de entrada para o tipo chamado tipo. O resultado é uma constante do tipo indicado. A conversão explícita de tipo pode ser omitida, caso não haja ambigüidade com relação ao tipo que a constante deva ter (por exemplo, quando passada como argumento para uma função não-sobrecarregada), caso onde é automaticamente transformada.

Também é possível especificar a transformação de tipo utilizando a sintaxe semelhante à chamada de função:

nome_do_tipo ( 'cadeia de caracteres' )

mas nem todos os nomes de tipo podem ser usados desta forma; veja a Seção 1.2.6 para obter mais informações.

As sintaxes ::, CAST(), e chamada de função também podem ser utilizadas para especificar conversão de tipo em tempo de execução para expressões arbitrárias, conforme discutido na Seção 1.2.6. Porém, a forma tipo 'cadeia de caracteres' somente pode ser utilizada para especificar tipo em constante literal. Outra restrição com relação a sintaxe tipo 'cadeia de caracteres' é que não pode ser usada em matrizes (arrays); deve ser usado :: ou CAST() para especificar tipo em matriz.

1.1.2.5. Constantes em forma de matriz

O formato geral de uma constante em forma de matriz é o seguinte:

'{ val1 delim val2 delim ... }'

onde delim é o caractere delimitador para o tipo, conforme registrado em sua entrada na tabela pg_type (para todos os tipos nativos é utilizado o caractere vírgula ","). Cada val pode ser tanto uma constante do tipo do elemento da matriz quanto uma submatriz. Um exemplo de uma constante em forma de matriz é

'{{1,2,3},{4,5,6},{7,8,9}}'

Esta constante é uma matriz bidimensional de 3x3, formada por 3 submatrizes de números inteiros.

Os elementos individuais da matriz podem ser colocados entre aspas ("), para evitar problemas de ambigüidade com respeito a espaços em branco. Sem aspas, o analisador de valores da matriz salta os espaços em branco precedentes.

(As constantes em forma de matriz são na verdade apenas um caso especial do tipo genérico discutido na seção anterior. A constante é inicialmente tratada como cadeia de caracteres e passada para a rotina de conversão de declaração de matriz. Uma especificação explícita do tipo pode ser necessária)

1.1.3. Operadores

Um operador é uma seqüência com até NAMEDATALEN-1 (por padrão 63) caracteres da seguinte lista:

+ - * / < > = ~ ! @ # % ^ & | ` ? $

Entretanto existem algumas poucas restrições relativas aos nomes dos operadores:

  • O $ (cifrão) não pode ser um operador de um único caractere, embora possa fazer parte do nome de um operador com vários caracteres.

  • As seqüências -- e /* não podem aparecer em nenhuma posição no nome do operador, porque são consideradas como início de comentário.

  • Um nome de operador com vários caracteres não pode terminar em + ou -, a não ser que o nome contenha também pelo menos um dos seguintes caracteres:

    ~ ! @ # % ^ & | ` ? $

    Por exemplo, @- é um nome de operador permitido, mas *- não é. Esta restrição permite ao PostgreSQL analisar consultas que estão de acordo com o padrão SQL sem haver necessidade de espaço entre os termos.

Ao trabalhar com nomes de operadores fora do padrão SQL, normalmente é necessário separar operadores adjacentes com espaço para evitar ambigüidade. Por exemplo, se for definido um operador unário esquerdo chamado @, não poderá ser escrito X*@Y; deverá ser escrito X* @Y para garantir que o PostgreSQL leia dois nomes de operadores e não apenas um.

1.1.4. Caracteres especiais

Alguns caracteres não alfanuméricos possuem um significado especial diferente de ser um operador. Os detalhes da utilização podem ser encontrados nos locais onde a sintaxe do respectivo elemento é descrita. Esta seção se destina apenas a informar a existência e fazer um resumo das finalidades destes caracteres.

  • O caractere cifrão ($) seguido por dígitos é utilizado para representar os parâmetros posicionais no corpo da definição de uma função. Em outros contextos o caractere cifrão pode fazer parte do nome de um operador.

  • Os parênteses (()) possuem seu significado usual de agrupar expressões e impor a precedência. Em alguns casos os parênteses são necessários como parte fixa da sintaxe de um determinado comando SQL.

  • Os colchetes ([]) são utilizados para selecionar elementos da matriz. Veja a Seção 5.12 para obter mais informações relativas às matrizes.

  • As vírgulas (,) são utilizadas em algumas construções sintáticas para separar os elementos da lista.

  • O ponto-e-vírgula (;) termina um comando SQL, não podendo aparecer em nenhum lugar dentro do comando, exceto dentro de constante do tipo cadeia de caracteres ou identificadores entre aspas.

  • Os dois-pontos (:) são utilizados para selecionar "faixas" em matrizes (veja a Seção 5.12). Em certos dialetos do SQL (como o SQL embutido), os dois-pontos são utilizados como prefixo dos nomes das variáveis.

  • O asterisco (*) possui um significado especial quando utilizado no comando SELECT ou na função de agregação COUNT.

  • O ponto (.) é utilizado nas constantes de ponto flutuante, e para separar os nomes de esquemas, tabelas e colunas.

1.1.5. Comentários

Um comentário é uma seqüência arbitrária de caracteres começando por dois hífens e prosseguindo até o fim da linha como, por exemplo:

-- Este é um comentário no padrão SQL92

Como alternativa, podem ser utilizados blocos de comentários no estilo C:

/* comentário de várias linhas
 * com: /* bloco de comentário aninhado */
 */

onde o comentário começa por /* se estendendo até encontrar a ocorrência de */. Estes blocos de comentários podem estar aninhados, conforme especificado no SQL99 (mas diferentemente da linguagem C), permitindo transformar em comentário grandes blocos de código que possuam blocos de comentários existentes.

Os comentários são removidos da declaração antes de prosseguir com a análise sintática sendo substituídos por espaço em branco.

1.1.6. Precedência léxica

A Tabela 1-1 mostra a precedência e a associatividade dos operadores no PostgreSQL. A maioria dos operadores possuem a mesma precedência e possuem associatividade esquerda. A precedência e a associatividade dos operadores está codificada no analisador, podendo ocasionar um comportamento contra-intuitivo; por exemplo, os operadores booleanos < e > possuem uma precedência diferente dos operadores booleanos <= e >=. Também, em alguns casos é necessário adicionar parênteses quando é utilizada a combinação de operadores unários e binários. Por exemplo,

SELECT 5 ! - 6;

será analisado como

SELECT 5 ! (- 6);

porque o analisador não possui a menor idéia -- até ser tarde demais -- que o ! é definido como operador unário direito (postfix), e não um operador binário colocado entre os operandos (infix). Neste caso, para obter o comportamento desejado deve ser escrito

SELECT (5 !) - 6;

Este é o preço a ser pago pela extensibilidade.

Tabela 1-1. Precedência dos operadores (decrescente)

Operador/ElementoAssociatividadeDescrição
.esquerdaseparador de nome de tabela/coluna
::esquerdatransformação de tipo estilo PostgreSQL
[ ]esquerdaseleção de elemento de matriz
-direitamenos unário
^esquerdaexponenciação
* / %esquerdamultiplicação, divisão, módulo
+ -esquerdaadição, subtração
IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL
ISNULL teste de nulo
NOTNULL teste de não nulo
(qualquer outro)esquerdatodos os operadores nativos e definidos pelo usuário
IN membro de um conjunto
BETWEEN intervalo fechado
OVERLAPS sobreposição de intervalo de tempo
LIKE ILIKE SIMILAR correspondência de padrão em cadeia de caracteres
< > menor que, maior que
=direitaigualdade, atribuição
NOTdireitanegação lógica
ANDesquerdaconjunção lógica
OResquerdadisjunção lógica

Observe que as regras de precedência dos operadores também se aplicam aos operadores definidos pelos usuários que possuem os mesmos nomes dos operadores nativos mencionados acima. Por exemplo, se for definido um operador "+" para algum tipo de dados personalizado, este terá a mesma precedência do operador "+" nativo, não importando o que faça.

Quando é utilizado um nome de operador qualificado pelo esquema na sintaxe do OPERATOR como, por exemplo,

SELECT 3 OPERATOR(pg_catalog.+) 4;

a construção OPERATOR é assumida como tendo a precedência padrão mostrada na Tabela 1-1 para "qualquer outro" operador. Isto é sempre verdade não importando qual é o nome específico do operador dentro de OPERATOR().

Notas

[1]

Sintaxe é parte da gramática que estuda as palavras enquanto elementos de uma frase, as suas relações de concordância, de subordinação e de ordem - Dicionário Eletrônico Houaiss. (N.T.)

[2]

A conversão em minúsculas das letras dos nomes que não estão entre aspas feita pelo PostgreSQL não é compatível com o padrão SQL, que estabelece a conversão em maiúsculas das letras dos nomes que não estão entre aspas. Portanto, foo deve ser equivalente a "FOO" e não a "foo" de acordo com o padrão. Se for desejado desenvolver aplicações portáveis, o nome deve ser colocado sempre entre aspas, ou nunca ser colocado entre aspas.