Variant(T1, T2, ..., TN) significa que cada linha desse tipo
tem um valor do tipo T1, T2, … ou TN, ou de nenhum deles (valor NULL).
A ordem dos tipos aninhados não importa: Variant(T1, T2) = Variant(T2, T1).
Os tipos aninhados podem ser quaisquer tipos, exceto Nullable(…), LowCardinality(Nullable(…)) e Variant(…).
Não é recomendado usar tipos semelhantes como variantes (por exemplo, tipos numéricos diferentes como
Variant(UInt32, Int64) ou tipos de data diferentes como Variant(Date, DateTime)),
porque trabalhar com valores desses tipos pode gerar ambiguidades. Por padrão, a criação desse tipo Variant gerará uma exceção, mas isso pode ser habilitado usando a configuração allow_suspicious_variant_typesCriando Variant
Variant na definição de uma coluna da tabela:
if/multiIf quando os argumentos não têm um tipo em comum (a configuração use_variant_as_common_type deve estar habilitada para isso):
use_variant_as_common_type deve estar habilitada para isso):
Lendo tipos aninhados de Variant como subcolunas
variant Variant(T1, T2, T3), poderá ler uma subcoluna do tipo T2 usando a sintaxe variant.T2;
essa subcoluna terá o tipo Nullable(T2) se T2 puder estar dentro de Nullable, e T2 caso contrário. Essa subcoluna
terá o mesmo tamanho da coluna Variant original e conterá valores NULL (ou valores vazios se T2 não puder estar dentro de Nullable)
em todas as linhas em que a coluna Variant original não tiver o tipo T2.
As subcolunas de Variant também podem ser lidas usando a função variantElement(variant_column, type_name).
Exemplos:
variantType(variant_column). Ela retorna um Enum com o nome do tipo variante de cada linha (ou 'None' se a linha for NULL).
Exemplo:
Conversão entre uma coluna Variant e outras colunas
Variant.
Convertendo uma coluna String em uma coluna Variant
String para Variant é feita fazendo o parsing de um valor do tipo Variant a partir do valor em string:
String para Variant, desative a configuração cast_string_to_dynamic_use_inference:
Convertendo uma coluna comum em uma coluna Variant
T em uma coluna Variant que contenha esse tipo:
String sempre é feita por meio de parsing; se você precisar converter uma coluna String para a variante String de um Variant sem fazer parsing, faça o seguinte:
Convertendo uma coluna Variant em uma coluna comum
Variant em uma coluna comum. Nesse caso, todas as variantes aninhadas serão convertidas para um tipo de destino:
Convertendo um Variant em outro Variant
Variant em outra coluna Variant, mas apenas se a coluna Variant de destino contiver todos os tipos aninhados da coluna Variant original:
Lendo o tipo Variant a partir dos dados
Variant. Durante o parsing dos dados, o ClickHouse tenta inserir o valor no tipo Variant mais apropriado.
Exemplo:
Comparando valores do tipo Variant
Variant só podem ser comparados com valores do mesmo tipo Variant.
Por padrão, os operadores de comparação usam a implementação padrão para Variant,
aplicando a comparação a cada tipo variante separadamente. Isso pode ser desativado usando a configuração use_variant_default_implementation_for_comparisons = 0
para usar as regras nativas de comparação de Variant descritas abaixo. Observação: ORDER BY sempre usa comparação nativa.
Regras nativas de comparação de Variant:
O resultado do operador < para os valores v1, com tipo subjacente T1, e v2, com tipo subjacente T2, de um tipo Variant(..., T1, ... T2, ...) é definido da seguinte forma:
- Se
T1 = T2 = T, o resultado seráv1.T < v2.T(os valores subjacentes serão comparados). - Se
T1 != T2, o resultado seráT1 < T2(os nomes dos tipos serão comparados).
Variant específico, pode usar uma das opções a seguir:
- Fazer cast do valor para o tipo
Variantcorrespondente:
- Compare a subcoluna
Variantcom o tipo necessário:
Array/Map/Tuple não podem estar dentro de Nullable e terão valores padrão em vez de NULL em linhas com tipos diferentes:
Variant não é permitido em chaves GROUP BY/ORDER BY; se quiser usá-lo, considere sua regra especial de comparação e habilite as configurações allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by.
Funções JSONExtract com Variant
JSONExtract* oferecem suporte ao tipo Variant:
Funções com argumentos Variant
Variant por meio de uma implementação padrão para Variant.
A partir da versão 26.1, quando uma função que não trata explicitamente tipos Variant recebe uma coluna Variant, o ClickHouse:
- Extrai cada tipo variante da coluna Variant
- Executa a função separadamente para cada tipo variante
- Combina os resultados adequadamente com base nos tipos de resultado
-
Tipos de resultado diferentes:
Variant(T1, T2, ...) -
Incompatibilidade de tipos:
NULLpara variants incompatíveis
Tratamento de erros: Quando uma função não consegue processar um tipo variant, apenas erros relacionados a tipo (ILLEGAL_TYPE_OF_ARGUMENT,
TYPE_MISMATCH, CANNOT_CONVERT_TYPE, NO_COMMON_TYPE) são capturados e resultam em NULL para essas linhas. Outros erros, como
divisão por zero ou falta de memória, são gerados normalmente para evitar que problemas reais sejam ocultados silenciosamente.
Comportamento em caso de incompatibilidade de tipo
variant_throw_on_type_mismatch controla o que acontece quando uma função é aplicada a uma coluna Variant e o tipo efetivamente armazenado em uma linha é incompatível com a função:
true(padrão) — gera uma exceção (ILLEGAL_TYPE_OF_ARGUMENT) na primeira linha incompatível.false— retornaNULLpara as linhas incompatíveis e mantém o resultado para as linhas compatíveis.