> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentação do tipo de dado Variant no ClickHouse

# Variant(T1, T2, ...)

Este tipo representa uma união de outros tipos de dados. O tipo `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(...).

<Note>
  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_types`
</Note>

<div id="creating-variant">
  ## Criando Variant
</div>

Usando o tipo `Variant` na definição de uma coluna da tabela:

```sql theme={null}
CREATE TABLE test (v Variant(UInt64, String, Array(UInt64))) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT v FROM test;
```

```text theme={null}
┌─v─────────────┐
│ ᴺᵁᴸᴸ          │
│ 42            │
│ Hello, World! │
│ [1,2,3]       │
└───────────────┘
```

Usando CAST de colunas comuns:

```sql theme={null}
SELECT toTypeName(variant) AS type_name, 'Hello, World!'::Variant(UInt64, String, Array(UInt64)) as variant;
```

```text theme={null}
┌─type_name──────────────────────────────┬─variant───────┐
│ Variant(Array(UInt64), String, UInt64) │ Hello, World! │
└────────────────────────────────────────┴───────────────┘
```

Usando as funções `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):

```sql theme={null}
SET use_variant_as_common_type = 1;
SELECT if(number % 2, number, range(number)) as variant FROM numbers(5);
```

```text theme={null}
┌─variant───┐
│ []        │
│ 1         │
│ [0,1]     │
│ 3         │
│ [0,1,2,3] │
└───────────┘
```

```sql theme={null}
SET use_variant_as_common_type = 1;
SELECT multiIf((number % 4) = 0, 42, (number % 4) = 1, [1, 2, 3], (number % 4) = 2, 'Hello, World!', NULL) AS variant FROM numbers(4);
```

```text theme={null}
┌─variant───────┐
│ 42            │
│ [1,2,3]       │
│ Hello, World! │
│ ᴺᵁᴸᴸ          │
└───────────────┘
```

Ao usar as funções 'array/map' se os elementos do array/valores do map não tiverem um tipo em comum (a configuração `use_variant_as_common_type` deve estar habilitada para isso):

```sql theme={null}
SET use_variant_as_common_type = 1;
SELECT array(range(number), number, 'str_' || toString(number)) as array_of_variants FROM numbers(3);
```

```text theme={null}
┌─array_of_variants─┐
│ [[],0,'str_0']    │
│ [[0],1,'str_1']   │
│ [[0,1],2,'str_2'] │
└───────────────────┘
```

```sql theme={null}
SET use_variant_as_common_type = 1;
SELECT map('a', range(number), 'b', number, 'c', 'str_' || toString(number)) as map_of_variants FROM numbers(3);
```

```text theme={null}
┌─map_of_variants───────────────┐
│ {'a':[],'b':0,'c':'str_0'}    │
│ {'a':[0],'b':1,'c':'str_1'}   │
│ {'a':[0,1],'b':2,'c':'str_2'} │
└───────────────────────────────┘
```

<div id="reading-variant-nested-types-as-subcolumns">
  ## Lendo tipos aninhados de Variant como subcolunas
</div>

O tipo Variant oferece suporte à leitura de um único tipo aninhado de uma coluna Variant usando o nome do tipo como subcoluna.
Assim, se você tiver a coluna `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:

```sql theme={null}
CREATE TABLE test (v Variant(UInt64, String, Array(UInt64))) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT v, v.String, v.UInt64, v.`Array(UInt64)` FROM test;
```

```text theme={null}
┌─v─────────────┬─v.String──────┬─v.UInt64─┬─v.Array(UInt64)─┐
│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ          │     ᴺᵁᴸᴸ │ []              │
│ 42            │ ᴺᵁᴸᴸ          │       42 │ []              │
│ Hello, World! │ Hello, World! │     ᴺᵁᴸᴸ │ []              │
│ [1,2,3]       │ ᴺᵁᴸᴸ          │     ᴺᵁᴸᴸ │ [1,2,3]         │
└───────────────┴───────────────┴──────────┴─────────────────┘
```

```sql theme={null}
SELECT toTypeName(v.String), toTypeName(v.UInt64), toTypeName(v.`Array(UInt64)`) FROM test LIMIT 1;
```

```text theme={null}
┌─toTypeName(v.String)─┬─toTypeName(v.UInt64)─┬─toTypeName(v.Array(UInt64))─┐
│ Nullable(String)     │ Nullable(UInt64)     │ Array(UInt64)               │
└──────────────────────┴──────────────────────┴─────────────────────────────┘
```

```sql theme={null}
SELECT v, variantElement(v, 'String'), variantElement(v, 'UInt64'), variantElement(v, 'Array(UInt64)') FROM test;
```

```text theme={null}
┌─v─────────────┬─variantElement(v, 'String')─┬─variantElement(v, 'UInt64')─┬─variantElement(v, 'Array(UInt64)')─┐
│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ                        │                        ᴺᵁᴸᴸ │ []                                 │
│ 42            │ ᴺᵁᴸᴸ                        │                          42 │ []                                 │
│ Hello, World! │ Hello, World!               │                        ᴺᵁᴸᴸ │ []                                 │
│ [1,2,3]       │ ᴺᵁᴸᴸ                        │                        ᴺᵁᴸᴸ │ [1,2,3]                            │
└───────────────┴─────────────────────────────┴─────────────────────────────┴────────────────────────────────────┘
```

Para saber qual variant está armazenado em cada linha, pode-se usar a função `variantType(variant_column)`. Ela retorna um `Enum` com o nome do tipo variante de cada linha (ou `'None'` se a linha for `NULL`).

Exemplo:

```sql theme={null}
CREATE TABLE test (v Variant(UInt64, String, Array(UInt64))) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT variantType(v) FROM test;
```

```text theme={null}
┌─variantType(v)─┐
│ None           │
│ UInt64         │
│ String         │
│ Array(UInt64)  │
└────────────────┘
```

```sql theme={null}
SELECT toTypeName(variantType(v)) FROM test LIMIT 1;
```

```text theme={null}
┌─toTypeName(variantType(v))──────────────────────────────────────────┐
│ Enum8('None' = -1, 'Array(UInt64)' = 0, 'String' = 1, 'UInt64' = 2) │
└─────────────────────────────────────────────────────────────────────┘
```

<div id="conversion-between-a-variant-column-and-other-columns">
  ## Conversão entre uma coluna Variant e outras colunas
</div>

Há 4 conversões possíveis que podem ser feitas com uma coluna do tipo `Variant`.

<div id="converting-a-string-column-to-a-variant-column">
  ### Convertendo uma coluna `String` em uma coluna `Variant`
</div>

A conversão de `String` para `Variant` é feita fazendo o parsing de um valor do tipo `Variant` a partir do valor em string:

```sql theme={null}
SELECT '42'::Variant(String, UInt64) AS variant, variantType(variant) AS variant_type
```

```text theme={null}
┌─variant─┬─variant_type─┐
│ 42      │ UInt64       │
└─────────┴──────────────┘
```

```sql theme={null}
SELECT '[1, 2, 3]'::Variant(String, Array(UInt64)) as variant, variantType(variant) as variant_type
```

```text theme={null}
┌─variant─┬─variant_type──┐
│ [1,2,3] │ Array(UInt64) │
└─────────┴───────────────┘
```

````sql theme={null}
SELECT CAST(map('key1', '42', 'key2', 'true', 'key3', '2020-01-01'), 'Map(String, Variant(UInt64, Bool, Date))') AS map_of_variants, mapApply((k, v) -> (k, variantType(v)), map_of_variants) AS map_of_variant_types```
````

```text theme={null}
┌─map_of_variants─────────────────────────────┬─map_of_variant_types──────────────────────────┐
│ {'key1':42,'key2':true,'key3':'2020-01-01'} │ {'key1':'UInt64','key2':'Bool','key3':'Date'} │
└─────────────────────────────────────────────┴───────────────────────────────────────────────┘
```

Para desativar o parsing durante a conversão de `String` para `Variant`, desative a configuração `cast_string_to_dynamic_use_inference`:

```sql theme={null}
SET cast_string_to_variant_use_inference = 0;
SELECT '[1, 2, 3]'::Variant(String, Array(UInt64)) as variant, variantType(variant) as variant_type
```

```text theme={null}
┌─variant───┬─variant_type─┐
│ [1, 2, 3] │ String       │
└───────────┴──────────────┘
```

<div id="converting-an-ordinary-column-to-a-variant-column">
  ### Convertendo uma coluna comum em uma coluna Variant
</div>

É possível converter uma coluna comum do tipo `T` em uma coluna `Variant` que contenha esse tipo:

```sql theme={null}
SELECT toTypeName(variant) AS type_name, [1,2,3]::Array(UInt64)::Variant(UInt64, String, Array(UInt64)) as variant, variantType(variant) as variant_name
```

```text theme={null}
┌─type_name──────────────────────────────┬─variant─┬─variant_name──┐
│ Variant(Array(UInt64), String, UInt64) │ [1,2,3] │ Array(UInt64) │
└────────────────────────────────────────┴─────────┴───────────────┘
```

Observação: a conversão a partir do 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:

```sql theme={null}
SELECT '[1, 2, 3]'::Variant(String)::Variant(String, Array(UInt64), UInt64) as variant, variantType(variant) as variant_type
```

```sql theme={null}
┌─variant───┬─variant_type─┐
│ [1, 2, 3] │ String       │
└───────────┴──────────────┘
```

<div id="converting-a-variant-column-to-an-ordinary-column">
  ### Convertendo uma coluna Variant em uma coluna comum
</div>

É possível converter uma coluna `Variant` em uma coluna comum. Nesse caso, todas as variantes aninhadas serão convertidas para um tipo de destino:

```sql theme={null}
CREATE TABLE test (v Variant(UInt64, String)) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('42.42');
SELECT v::Nullable(Float64) FROM test;
```

```text theme={null}
┌─CAST(v, 'Nullable(Float64)')─┐
│                         ᴺᵁᴸᴸ │
│                           42 │
│                        42.42 │
└──────────────────────────────┘
```

<div id="converting-a-variant-to-another-variant">
  ### Convertendo um Variant em outro Variant
</div>

É possível converter uma coluna `Variant` em outra coluna `Variant`, mas apenas se a coluna `Variant` de destino contiver todos os tipos aninhados da coluna `Variant` original:

```sql theme={null}
CREATE TABLE test (v Variant(UInt64, String)) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('String');
SELECT v::Variant(UInt64, String, Array(UInt64)) FROM test;
```

```text theme={null}
┌─CAST(v, 'Variant(UInt64, String, Array(UInt64))')─┐
│ ᴺᵁᴸᴸ                                              │
│ 42                                                │
│ String                                            │
└───────────────────────────────────────────────────┘
```

<div id="reading-variant-type-from-the-data">
  ## Lendo o tipo Variant a partir dos dados
</div>

Todos os formatos de texto (TSV, CSV, CustomSeparated, Values, JSONEachRow etc.) oferecem suporte à leitura do tipo `Variant`. Durante o parsing dos dados, o ClickHouse tenta inserir o valor no tipo Variant mais apropriado.

Exemplo:

```sql theme={null}
SELECT
    v,
    variantElement(v, 'String') AS str,
    variantElement(v, 'UInt64') AS num,
    variantElement(v, 'Float64') AS float,
    variantElement(v, 'DateTime') AS date,
    variantElement(v, 'Array(UInt64)') AS arr
FROM format(JSONEachRow, 'v Variant(String, UInt64, Float64, DateTime, Array(UInt64))', $$
{"v" : "Hello, World!"},
{"v" : 42},
{"v" : 42.42},
{"v" : "2020-01-01 00:00:00"},
{"v" : [1, 2, 3]}
$$)
```

```text theme={null}
┌─v───────────────────┬─str───────────┬──num─┬─float─┬────────────────date─┬─arr─────┐
│ Hello, World!       │ Hello, World! │ ᴺᵁᴸᴸ │  ᴺᵁᴸᴸ │                ᴺᵁᴸᴸ │ []      │
│ 42                  │ ᴺᵁᴸᴸ          │   42 │  ᴺᵁᴸᴸ │                ᴺᵁᴸᴸ │ []      │
│ 42.42               │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ │ 42.42 │                ᴺᵁᴸᴸ │ []      │
│ 2020-01-01 00:00:00 │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ │  ᴺᵁᴸᴸ │ 2020-01-01 00:00:00 │ []      │
│ [1,2,3]             │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ │  ᴺᵁᴸᴸ │                ᴺᵁᴸᴸ │ [1,2,3] │
└─────────────────────┴───────────────┴──────┴───────┴─────────────────────┴─────────┘
```

<div id="comparing-values-of-variant-data">
  ## Comparando valores do tipo Variant
</div>

Valores de um tipo `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](#functions-with-variant-arguments),
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).

Exemplos:

```sql theme={null}
SET allow_suspicious_types_in_order_by = 1;
CREATE TABLE test (v1 Variant(String, UInt64, Array(UInt32)), v2 Variant(String, UInt64, Array(UInt32))) ENGINE=Memory;
INSERT INTO test VALUES (42, 42), (42, 43), (42, 'abc'), (42, [1, 2, 3]), (42, []), (42, NULL);
```

```sql theme={null}
SELECT v2, variantType(v2) AS v2_type FROM test ORDER BY v2;
```

```text theme={null}
┌─v2──────┬─v2_type───────┐
│ []      │ Array(UInt32) │
│ [1,2,3] │ Array(UInt32) │
│ abc     │ String        │
│ 42      │ UInt64        │
│ 43      │ UInt64        │
│ ᴺᵁᴸᴸ    │ None          │
└─────────┴───────────────┘
```

```sql theme={null}
SELECT v1, variantType(v1) AS v1_type, v2, variantType(v2) AS v2_type, v1 = v2, v1 < v2, v1 > v2 FROM test;
```

```text theme={null}
┌─v1─┬─v1_type─┬─v2──────┬─v2_type───────┬─equals(v1, v2)─┬─less(v1, v2)─┬─greater(v1, v2)─┐
│ 42 │ UInt64  │ 42      │ UInt64        │              1 │            0 │               0 │
│ 42 │ UInt64  │ 43      │ UInt64        │              0 │            1 │               0 │
│ 42 │ UInt64  │ abc     │ String        │              0 │            0 │               1 │
│ 42 │ UInt64  │ [1,2,3] │ Array(UInt32) │              0 │            0 │               1 │
│ 42 │ UInt64  │ []      │ Array(UInt32) │              0 │            0 │               1 │
│ 42 │ UInt64  │ ᴺᵁᴸᴸ    │ None          │              0 │            1 │               0 │
└────┴─────────┴─────────┴───────────────┴────────────────┴──────────────┴─────────────────┘

```

Se você precisar encontrar a linha com um valor `Variant` específico, pode usar uma das opções a seguir:

* Fazer cast do valor para o tipo `Variant` correspondente:

```sql theme={null}
SELECT * FROM test WHERE v2 == [1,2,3]::Array(UInt32)::Variant(String, UInt64, Array(UInt32));
```

```text theme={null}
┌─v1─┬─v2──────┐
│ 42 │ [1,2,3] │
└────┴─────────┘
```

* Compare a subcoluna `Variant` com o tipo necessário:

```sql theme={null}
SELECT * FROM test WHERE v2.`Array(UInt32)` == [1,2,3] -- ou usando variantElement(v2, 'Array(UInt32)')
```

```text theme={null}
┌─v1─┬─v2──────┐
│ 42 │ [1,2,3] │
└────┴─────────┘
```

Às vezes, pode ser útil fazer uma verificação adicional do tipo Variant, pois subcolunas com tipos complexos como `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:

```sql theme={null}
SELECT v2, v2.`Array(UInt32)`, variantType(v2) FROM test WHERE v2.`Array(UInt32)` == [];
```

```text theme={null}
┌─v2───┬─v2.Array(UInt32)─┬─variantType(v2)─┐
│ 42   │ []               │ UInt64          │
│ 43   │ []               │ UInt64          │
│ abc  │ []               │ String          │
│ []   │ []               │ Array(UInt32)   │
│ ᴺᵁᴸᴸ │ []               │ None            │
└──────┴──────────────────┴─────────────────┘
```

```sql theme={null}
SELECT v2, v2.`Array(UInt32)`, variantType(v2) FROM test WHERE variantType(v2) == 'Array(UInt32)' AND v2.`Array(UInt32)` == [];
```

```text theme={null}
┌─v2─┬─v2.Array(UInt32)─┬─variantType(v2)─┐
│ [] │ []               │ Array(UInt32)   │
└────┴──────────────────┴─────────────────┘
```

**Observação:** valores de variantes com tipos numéricos diferentes são considerados variantes distintas e não são comparados entre si; em vez disso, seus nomes de tipos são comparados.

Exemplo:

```sql theme={null}
SET allow_suspicious_variant_types = 1;
CREATE TABLE test (v Variant(UInt32, Int64)) ENGINE=Memory;
INSERT INTO test VALUES (1::UInt32), (1::Int64), (100::UInt32), (100::Int64);
SELECT v, variantType(v) FROM test ORDER by v;
```

```text theme={null}
┌─v───┬─variantType(v)─┐
│ 1   │ Int64          │
│ 100 │ Int64          │
│ 1   │ UInt32         │
│ 100 │ UInt32         │
└─────┴────────────────┘
```

**Observação**: por padrão, o tipo `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`.

<div id="jsonextract-functions-with-variant">
  ## Funções JSONExtract com Variant
</div>

Todas as funções `JSONExtract*` oferecem suporte ao tipo `Variant`:

```sql theme={null}
SELECT JSONExtract('{"a" : [1, 2, 3]}', 'a', 'Variant(UInt32, String, Array(UInt32))') AS variant, variantType(variant) AS variant_type;
```

```text theme={null}
┌─variant─┬─variant_type──┐
│ [1,2,3] │ Array(UInt32) │
└─────────┴───────────────┘
```

```sql theme={null}
SELECT JSONExtract('{"obj" : {"a" : 42, "b" : "Hello", "c" : [1,2,3]}}', 'obj', 'Map(String, Variant(UInt32, String, Array(UInt32)))') AS map_of_variants, mapApply((k, v) -> (k, variantType(v)), map_of_variants) AS map_of_variant_types
```

```text theme={null}
┌─map_of_variants──────────────────┬─map_of_variant_types────────────────────────────┐
│ {'a':42,'b':'Hello','c':[1,2,3]} │ {'a':'UInt32','b':'String','c':'Array(UInt32)'} │
└──────────────────────────────────┴─────────────────────────────────────────────────┘
```

```sql theme={null}
SELECT JSONExtractKeysAndValues('{"a" : 42, "b" : "Hello", "c" : [1,2,3]}', 'Variant(UInt32, String, Array(UInt32))') AS variants, arrayMap(x -> (x.1, variantType(x.2)), variants) AS variant_types
```

```text theme={null}
┌─variants───────────────────────────────┬─variant_types─────────────────────────────────────────┐
│ [('a',42),('b','Hello'),('c',[1,2,3])] │ [('a','UInt32'),('b','String'),('c','Array(UInt32)')] │
└────────────────────────────────────────┴───────────────────────────────────────────────────────┘
```

<div id="functions-with-variant-arguments">
  ## Funções com argumentos Variant
</div>

A maioria das funções no ClickHouse oferece suporte automático a argumentos do tipo `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:

1. Extrai cada tipo variante da coluna Variant
2. Executa a função separadamente para cada tipo variante
3. Combina os resultados adequadamente com base nos tipos de resultado

Isso permite usar funções comuns com colunas Variant sem precisar de tratamento especial.

**Exemplo:**

```sql theme={null}
CREATE TABLE test (v Variant(UInt32, String)) ENGINE = Memory;
INSERT INTO test VALUES (42), ('hello'), (NULL);
SELECT *, toTypeName(v) FROM test WHERE v = 42;
```

```text theme={null}
   ┌─v──┬─toTypeName(v)───────────┐
1. │ 42 │ Variant(String, UInt32) │
   └────┴─────────────────────────┘
```

O operador de comparação é aplicado automaticamente a cada tipo Variant separadamente, permitindo filtrar colunas Variant.

**Comportamento do tipo de resultado:**

O tipo de resultado depende do que a função retorna para cada variant:

* **Tipos de resultado diferentes**: `Variant(T1, T2, ...)`

  ```sql theme={null}
  CREATE TABLE test2 (v Variant(UInt64, Float64)) ENGINE = Memory;
  INSERT INTO test2 VALUES (42::UInt64), (42.42);
  SELECT v + 1 AS result, toTypeName(result) FROM test2;
  ```

  ```text theme={null}
  ┌─result─┬─toTypeName(plus(v, 1))──┐
  │     43 │ Variant(Float64, UInt64) │
  │  43.42 │ Variant(Float64, UInt64) │
  └────────┴─────────────────────────┘
  ```

* **Incompatibilidade de tipos**: `NULL` para variants incompatíveis

  ```sql theme={null}
  CREATE TABLE test3 (v Variant(Array(UInt32), UInt32)) ENGINE = Memory;
  INSERT INTO test3 VALUES ([1,2,3]), (42);
  SELECT v + 10 AS result, toTypeName(result) FROM test3;
  ```

  ```text theme={null}
  ┌─result─┬─toTypeName(plus(v, 10))─┐
  │   ᴺᵁᴸᴸ │ Nullable(UInt64)        │
  │     52 │ Nullable(UInt64)        │
  └────────┴─────────────────────────┘
  ```

<Note>
  **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.
</Note>

<div id="variant-type-mismatch-behavior">
  ### Comportamento em caso de incompatibilidade de tipo
</div>

A configuração `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` — retorna `NULL` para as linhas incompatíveis e mantém o resultado para as linhas compatíveis.

**Exemplo:**

```sql theme={null}
CREATE TABLE test (v Variant(String, UInt64)) ENGINE = Memory;
INSERT INTO test VALUES ('hello'), (42), ('foo');

-- Padrão (lançar exceção em incompatibilidade): length() não aceita UInt64, então a consulta lança uma exceção.
SELECT length(v) FROM test;  -- lança ILLEGAL_TYPE_OF_ARGUMENT

-- Com exceção desativada: linhas incompatíveis retornam NULL.
SET variant_throw_on_type_mismatch = false;
SELECT v, length(v) FROM test ORDER BY v::String NULLS LAST;
```

```text theme={null}
┌─v─────┬─length(v)─┐
│ foo   │         3 │
│ hello │         5 │
│ 42    │      ᴺᵁᴸᴸ │
└───────┴───────────┘
```
