Variant(T1, T2, ..., TN) significa que cada fila de este tipo
tiene un valor de tipo T1, T2, … TN o ninguno de ellos (valor NULL).
El orden de los tipos anidados no importa: Variant(T1, T2) = Variant(T2, T1).
Los tipos anidados pueden ser tipos arbitrarios, excepto los tipos Nullable(…), LowCardinality(Nullable(…)) y Variant(…).
No se recomienda usar tipos similares como variantes (por ejemplo, distintos tipos numéricos como
Variant(UInt32, Int64) o distintos tipos de fecha como Variant(Date, DateTime)),
porque trabajar con valores de esos tipos puede dar lugar a ambigüedades. De forma predeterminada, crear ese tipo Variant generará una excepción, pero puede habilitarse mediante la configuración allow_suspicious_variant_typesCreación de Variant
Variant en la definición de una columna de una tabla:
if/multiIf cuando los argumentos no tienen un tipo común (para ello, debe estar habilitada la configuración use_variant_as_common_type):
use_variant_as_common_type debe estar habilitada):
Lectura de tipos Variant anidados como subcolumnas
variant Variant(T1, T2, T3), puede leer una subcolumna de tipo T2 con la sintaxis variant.T2;
esta subcolumna tendrá el tipo Nullable(T2) si T2 puede estar dentro de Nullable, y T2 en caso contrario. Esta subcolumna
tendrá el mismo tamaño que la columna Variant original y contendrá valores NULL (o valores vacíos si T2 no puede estar dentro de Nullable)
en todas las filas en las que la columna Variant original no tenga el tipo T2.
Las subcolumnas de Variant también se pueden leer usando la función variantElement(variant_column, type_name).
Ejemplos:
variantType(variant_column). Devuelve un Enum con el nombre del tipo de variante para cada fila (o 'None' si la fila es NULL).
Ejemplo:
Conversión entre una columna Variant y otras columnas
Variant.
Conversión de una columna String a una columna Variant
String a Variant se realiza analizando un valor de tipo Variant a partir de la cadena:
String a Variant, puede desactivar la opción cast_string_to_dynamic_use_inference:
Convertir una columna ordinaria en una columna Variant
T en una columna Variant que contenga ese tipo:
String siempre se realiza mediante análisis sintáctico; si necesita convertir una columna String a la variante String de un Variant sin realizar ese análisis, puede hacer lo siguiente:
Conversión de una columna Variant en una columna ordinaria
Variant en una columna ordinaria. En este caso, todas las variantes anidadas se convertirán al tipo de destino:
Conversión de un Variant a otro Variant
Variant en otra columna Variant, pero solo si la columna Variant de destino contiene todos los tipos anidados de la columna Variant original:
Lectura del tipo Variant a partir de los datos
Variant. Durante el análisis de los datos, ClickHouse intenta insertar el valor en el tipo de variante más adecuado.
Ejemplo:
Comparación de valores del tipo Variant
Variant solo pueden compararse con valores del mismo tipo Variant.
De forma predeterminada, los operadores de comparación usan la implementación predeterminada para Variant,
aplicando la comparación a cada tipo variante por separado. Esto puede deshabilitarse mediante la configuración use_variant_default_implementation_for_comparisons = 0
para usar las reglas nativas de comparación de Variant que se describen a continuación. Nota: ORDER BY siempre usa la comparación nativa.
Reglas nativas de comparación de Variant:
El resultado del operador < para los valores v1 con tipo subyacente T1 y v2 con tipo subyacente T2 de un tipo Variant(..., T1, ... T2, ...) se define de la siguiente manera:
- Si
T1 = T2 = T, el resultado seráv1.T < v2.T(se compararán los valores subyacentes). - Si
T1 != T2, el resultado seráT1 < T2(se compararán los nombres de tipo).
Variant específico, puede hacer una de las siguientes opciones:
- Convertir el valor al tipo
Variantcorrespondiente:
- Compare la subcolumna
Variantcon el tipo requerido:
Array/Map/Tuple no pueden estar dentro de Nullable y tendrán valores predeterminados en lugar de NULL en las filas con tipos distintos:
Variant no está permitido en las claves GROUP BY/ORDER BY; si desea usarlo, tenga en cuenta su regla especial de comparación y habilite las opciones allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by.
Funciones JSONExtract con Variant
JSONExtract* admiten el tipo Variant:
Funciones con argumentos de tipo Variant
Variant mediante una implementación predeterminada para Variant.
A partir de la versión 26.1, cuando una función que no maneja explícitamente tipos Variant recibe una columna Variant, ClickHouse:
- Extrae cada tipo Variant de la columna Variant
- Ejecuta la función por separado para cada tipo Variant
- Combina los resultados de forma adecuada según los tipos de resultado
-
Tipos de resultado diferentes:
Variant(T1, T2, ...) -
Incompatibilidad de tipos:
NULLpara variantes incompatibles
Manejo de errores: Cuando una función no puede procesar un tipo Variant, solo se capturan los errores relacionados con tipos (ILLEGAL_TYPE_OF_ARGUMENT,
TYPE_MISMATCH, CANNOT_CONVERT_TYPE, NO_COMMON_TYPE) y el resultado es NULL para esas filas. Otros errores, como
la división por cero o la falta de memoria, se generan normalmente para evitar ocultar silenciosamente problemas reales.
Comportamiento ante incompatibilidades de tipos
variant_throw_on_type_mismatch controla lo que ocurre cuando se aplica una función a una columna Variant y el tipo real almacenado en una fila es incompatible con la función:
true(predeterminado) — genera una excepción (ILLEGAL_TYPE_OF_ARGUMENT) en la primera fila incompatible.false— devuelveNULLpara las filas incompatibles y conserva el resultado para las filas compatibles.