Análise sintática de consultas
- Um parser SQL completo (um parser por descida recursiva).
- Um parser de formato de dados (um parser de fluxo rápido).
INSERT, que usa ambos os parsers.
Vamos examinar a consulta abaixo:
INSERT usa ambos os analisadores.
O fragmento INSERT INTO t VALUES é analisado pelo analisador completo,
e os dados (1, 'Hello, world'), (2, 'abc'), (3, 'def') são analisados pelo analisador de formato de dados, ou analisador rápido de fluxo.
Ativando o analisador completo
Ativando o analisador completo
Você também pode ativar o analisador completo para os dados
usando a configuração
input_format_values_interpret_expressions.Quando a configuração mencionada acima é definida como 1,
o ClickHouse primeiro tenta analisar os valores com o analisador rápido de fluxo.
Se isso falhar, o ClickHouse tenta usar o analisador completo para os dados, tratando-os como uma expressão SQL.INSERT grandes, que é a forma recomendada de inserir seus dados no ClickHouse.
Ao usar o formato Values em uma consulta INSERT,
pode parecer que os dados são analisados da mesma forma que as expressões em uma consulta SELECT, mas não é esse o caso.
O formato Values é muito mais limitado.
O restante desta seção aborda o analisador completo.
Para mais informações sobre analisadores de formato, consulte a seção Formatos.
Espaços
- Pode haver qualquer quantidade de caracteres de espaço entre construções sintáticas (inclusive no início e no fim de uma consulta).
- Os caracteres de espaço incluem espaço, tabulação, quebra de linha, CR e avanço de página.
Comentários
- Comentários no estilo SQL começam com
--,#!ou#e vão até o fim da linha. O espaço após--e#!pode ser omitido. - Comentários no estilo C:
//(ou mais de 2 caracteres/) seguido de texto até o fim da linha. Não é necessário espaço após/.- Podem ir de
/*a*/para comentários de várias linhas. Também não é necessário espaço. - Comentários no estilo C podem ser aninhados.
Palavras-chave
- ao padrão SQL. Por exemplo,
SELECT,selecteSeLeCtsão todos válidos. - à implementação de alguns SGBDs populares (MySQL ou Postgres). Por exemplo,
DateTimeé o mesmo quedatetime.
Você pode verificar se um nome de tipo de dado diferencia maiúsculas de minúsculas na tabela system.data_type_families.
table_name tiver uma coluna com o nome "FROM":
Identificadores
- Nomes de cluster, database, tabela, partição e coluna.
- Funções.
- Tipos de dados.
- Aliases de expressão.
^[a-zA-Z_][0-9a-zA-Z_]*$ e não podem ser iguais a palavras-chave.
Veja a tabela abaixo com exemplos de identificadores válidos e inválidos:
| Identificadores válidos | Identificadores inválidos |
|---|---|
xyz, _internal, Id_with_underscores_123_ | 1x, tom@gmail.com, äußerst_schön |
"id", `id`.
As mesmas regras de escape aplicáveis a identificadores entre aspas também se aplicam a literais de string. Veja String para mais detalhes.
Literais
String
- usando uma aspa simples antes, em que o caractere de aspas simples
'(e somente esse caractere) pode ser escapado como'', ou - usando uma barra invertida antes, com as seguintes sequências de escape compatíveis listadas na tabela abaixo.
A barra invertida perde seu significado especial, ou seja, é interpretada literalmente caso preceda caracteres diferentes dos listados abaixo.
| Escape compatível | Descrição |
|---|---|
\xHH | Especificação de caractere de 8 bits seguida por qualquer quantidade de dígitos hexadecimais (H). |
\N | reservado, não faz nada (por exemplo, SELECT 'a\Nb' retorna ab) |
\a | alerta |
\b | retrocesso |
\e | caractere de escape |
\f | avanço de página |
\n | quebra de linha |
\r | retorno de carro |
\t | tabulação horizontal |
\v | tabulação vertical |
\0 | caractere nulo |
\\ | barra invertida |
\' (ou '') | aspas simples |
\" | aspas duplas |
` | acento grave |
\/ | barra normal |
\= | sinal de igual |
| Caracteres de controle ASCII (c <= 31). |
Em literais de string, você precisa escapar pelo menos
' e \ usando os códigos de escape \' (ou '') e \\.Numérico
- Se o literal for precedido por um sinal de menos
-, o token será ignorado e o resultado será negado após a análise. - O literal numérico é analisado primeiro como um inteiro sem sinal de 64 bits, usando a função strtoull.
- Se o valor tiver o prefixo
0bou0x/0X, o número será analisado como binário ou hexadecimal, respectivamente. - Se o valor for negativo e sua magnitude absoluta for maior que 263, um erro será retornado.
- Se o valor tiver o prefixo
- Se isso não funcionar, o valor será então analisado como um número de ponto flutuante usando a função strtod.
- Caso contrário, um erro será retornado.
1é analisado comoUInt8256é analisado comoUInt16.
ImportanteValores inteiros maiores que 64 bits (Isso contorna o algoritmo acima e analisa o inteiro com uma rotina que oferece suporte a precisão arbitrária.Caso contrário, o literal será analisado como um número de ponto flutuante e, portanto, estará sujeito à perda de precisão por truncamento.
UInt128, Int128, UInt256, Int256) precisam ser convertidos para um tipo maior para serem analisados corretamente:_ dentro de literais numéricos são ignorados e podem ser usados para melhorar a legibilidade.
Há suporte aos seguintes literais numéricos:
| Literal numérico | Exemplos |
|---|---|
| Inteiros | 1, 10_000_000, 18446744073709551615, 01 |
| Decimais | 0.1 |
| Notação exponencial | 1e100, -1e-100 |
| Números de ponto flutuante | 123.456, inf, nan |
| Hexadecimal | 0xc0fe |
| String hexadecimal compatível com SQL Standard | x'c0fe' |
| Binário | 0b1101 |
| String binária compatível com SQL Standard | b'1101' |
Literais octais não são suportados para evitar erros acidentais de interpretação.
Compostos
[]: [1, 2, 3]. Tuplas são construídas com (): (1, 'Hello, world!', 2).
Tecnicamente, eles não são literais, mas expressões com o operador de criação de array e o operador de criação de tupla, respectivamente.
Um array deve consistir em pelo menos um item, e uma tupla deve ter pelo menos dois itens.
Há um caso separado em que tuplas aparecem na cláusula
IN de uma consulta SELECT.
Os resultados da consulta podem incluir tuplas, mas tuplas não podem ser salvas em um banco de dados (exceto em tabelas que usam o motor Memory).NULL
NULL é usado para indicar que um valor está ausente.
Para armazenar NULL em um campo de uma tabela, ele deve ser do tipo Nullable.
Observe o seguinte sobre
NULL:- Dependendo do formato de dados (de entrada ou de saída),
NULLpode ter uma representação diferente. Para mais informações, consulte formatos de dados. - O tratamento de
NULLtem nuances. Por exemplo, se pelo menos um dos argumentos de uma operação de comparação forNULL, o resultado dessa operação também seráNULL. O mesmo vale para multiplicação, adição e outras operações. Recomendamos ler a documentação de cada operação. - Em consultas, você pode verificar
NULLusando os operadoresIS NULLeIS NOT NULL, além das funções relacionadasisNulleisNotNull.
Heredoc
$.
Por exemplo:
- Um valor entre dois heredocs é processado “como está”.
Definição e uso de parâmetros de consulta
SET param_<name>=<value>— usando um comandoSETem uma consulta.--param_<name>='<value>'— como argumento para oclickhouse-clientna linha de comando.param_<name>=<value>— como parâmetro de consulta na URL da interface HTTP.
{<name>: <datatype>}, em que <name> é o nome do parâmetro de consulta e <datatype> é o tipo de dado para o qual ele será convertido.
Exemplo com o comando SET
Exemplo com o comando SET
Por exemplo, o SQL a seguir define parâmetros chamados
a, b, c e d — cada um com um tipo de dado diferente:Exemplo com clickhouse-client
Exemplo com clickhouse-client
Se você estiver usando o Se o parâmetro de consulta representar o nome de um banco de dados, tabela, função ou outro identificador, use
clickhouse-client, os parâmetros serão especificados como --param_name=value. Por exemplo, o parâmetro a seguir tem o nome message e é recuperado como String:Identifier como tipo. Por exemplo, a consulta a seguir retorna linhas de uma tabela chamada uk_price_paid:Exemplo com a interface HTTP
Exemplo com a interface HTTP
Os parâmetros de consulta podem ser passados como parâmetros de consulta na URL com o prefixo
param_. Por exemplo:Exemplo com a interface web
Exemplo com a interface web
A interface web integrada (
play.html) detecta automaticamente placeholders de parâmetro no formato {name:Type} na consulta e exibe campos de entrada identificados para cada parâmetro. Os valores dos parâmetros são incluídos na solicitação HTTP e também persistidos na URL da página para permitir favoritos e compartilhamento.Os parâmetros de consulta não são substituições genéricas de texto que podem ser usadas em locais arbitrários de consultas SQL arbitrárias.
Eles foram projetados principalmente para funcionar em Instruções
SELECT, no lugar de identificadores ou literais.Funções
().
Ao contrário do SQL padrão, os parênteses são obrigatórios, mesmo para uma lista de argumentos vazia.
Por exemplo:
A sintaxe das funções de agregação sem parâmetros é a mesma das funções regulares.
Operadores
Tipos de dados e motores de tabela do banco de dados
CREATE são escritos da mesma forma que identificadores ou funções.
Em outras palavras, eles podem ou não conter uma lista de argumentos entre parênteses.
Para mais informações, consulte as seções:
Expressões
- uma função
- um identificador
- um literal
- a aplicação de um operador
- uma expressão entre parênteses
- uma subconsulta
- um asterisco
Aliases de expressão
| Parte da sintaxe | Descrição | Exemplo | Observações |
|---|---|---|---|
AS | A palavra-chave usada para definir aliases. Você pode definir o alias de um nome de tabela ou de uma coluna em uma cláusula SELECT sem usar a palavra-chave AS. | SELECT table_name_alias.column_name FROM table_name table_name_alias. | Na função CAST, a palavra-chave AS tem outro significado. Consulte a descrição da função. |
expr | Qualquer expressão suportada pelo ClickHouse. | SELECT column_name * 2 AS double FROM some_table | |
alias | Nome de expr. Os aliases devem seguir a sintaxe de identificadores. | SELECT "table t".column_name FROM table_name AS "table t". |
Notas de uso
- Aliases são globais em uma consulta ou subconsulta, e você pode definir um alias em qualquer parte da consulta para qualquer expressão. Por exemplo:
- Aliases não ficam visíveis em subconsultas nem entre subconsultas. Por exemplo, ao executar a consulta a seguir, ClickHouse gera a exceção
Unknown identifier: num:
- Se um alias for definido para as colunas de resultado na cláusula
SELECTde uma subconsulta, essas colunas ficam visíveis na consulta externa. Por exemplo:
- Tenha cuidado com aliases que sejam iguais a nomes de colunas ou tabelas. Vamos considerar o exemplo a seguir:
t com a coluna b.
Em seguida, ao selecionar os dados, definimos o alias sum(b) AS b.
Como os aliases têm escopo global,
ClickHouse substituiu o literal b na expressão argMax(a, b) pela expressão sum(b).
Essa substituição causou a exceção.
Você pode alterar esse comportamento padrão definindo prefer_column_name_to_alias como
1.Asterisco
SELECT, um asterisco pode substituir a expressão.
Para mais informações, consulte a seção SELECT.