Passer au contenu principal
Ce type représente une union d’autres types de données. Le type Variant(T1, T2, ..., TN) signifie que chaque ligne de ce type contient une valeur de type T1, T2, … , TN, ou d’aucun de ces types (valeur NULL). L’ordre des types imbriqués n’a pas d’importance : Variant(T1, T2) = Variant(T2, T1). Les types imbriqués peuvent être de n’importe quel type, à l’exception de Nullable(…), LowCardinality(Nullable(…)) et Variant(…).
Il n’est pas recommandé d’utiliser comme variantes des types similaires (par exemple, différents types numériques comme Variant(UInt32, Int64) ou différents types de date comme Variant(Date, DateTime)), car manipuler des valeurs de ces types peut entraîner des ambiguïtés. Par défaut, la création d’un tel type Variant provoque une exception, mais cela peut être activé à l’aide du paramètre allow_suspicious_variant_types

Création du type Variant

Utilisation du type Variant dans la définition d’une colonne d’une table :
Utilisation de CAST sur des colonnes ordinaires :
Utilisation des fonctions if/multiIf lorsque les arguments n’ont pas de type commun (le paramètre use_variant_as_common_type doit être activé pour que cela fonctionne) :
Utilisation des fonctions ‘array/map’ si les éléments de l’array/les valeurs de la map n’ont pas de type commun (le paramètre use_variant_as_common_type doit être activé pour cela) :

Lecture des types imbriqués de Variant comme sous-colonnes

Le type Variant permet de lire un seul type imbriqué à partir d’une colonne Variant en utilisant le nom du type comme sous-colonne. Ainsi, si vous avez la colonne variant Variant(T1, T2, T3), vous pouvez lire une sous-colonne de type T2 avec la syntaxe variant.T2. Cette sous-colonne aura le type Nullable(T2) si T2 peut être inclus dans Nullable, et T2 sinon. Cette sous-colonne aura la même taille que la colonne Variant d’origine et contiendra des valeurs NULL (ou des valeurs vides si T2 ne peut pas être inclus dans Nullable) dans toutes les lignes où la colonne Variant d’origine n’est pas du type T2. Les sous-colonnes de Variant peuvent également être lues à l’aide de la fonction variantElement(variant_column, type_name). Exemples :
Pour savoir quel type de variante est stocké dans chaque ligne, vous pouvez utiliser la fonction variantType(variant_column). Elle renvoie un Enum contenant le nom du type de variante pour chaque ligne (ou 'None' si la ligne est NULL). Exemple :

Conversion entre une colonne Variant et d’autres colonnes

Il existe 4 conversions possibles avec une colonne de type Variant.

Conversion d’une colonne String en colonne Variant

La conversion de String vers Variant s’effectue en analysant une valeur de type Variant à partir de la valeur String :
Pour désactiver l’analyse lors de la conversion de String en Variant, vous pouvez désactiver le paramètre cast_string_to_dynamic_use_inference :

Conversion d’une colonne ordinaire en colonne Variant

Il est possible de convertir une colonne ordinaire de type T en colonne Variant contenant ce type :
Remarque : la conversion à partir du type String passe toujours par une analyse syntaxique. Si vous devez convertir une colonne String en variante String d’un Variant sans analyse syntaxique, vous pouvez procéder comme suit :

Conversion d’une colonne Variant en colonne ordinaire

Il est possible de convertir une colonne Variant en colonne ordinaire. Dans ce cas, toutes les variantes imbriquées seront converties en un type cible :

Conversion d’un Variant en un autre Variant

Il est possible de convertir une colonne Variant en une autre colonne Variant, mais uniquement si la colonne Variant de destination contient tous les types imbriqués du Variant d’origine :

Lecture du type Variant à partir des données

Tous les formats texte (TSV, CSV, CustomSeparated, Values, JSONEachRow, etc.) prennent en charge la lecture du type Variant. Lors de l’analyse des données, ClickHouse essaie d’insérer la valeur dans le type de variante le plus adapté. Exemple :

Comparaison des valeurs de type Variant

Les valeurs d’un type Variant ne peuvent être comparées qu’avec des valeurs du même type Variant. Par défaut, les opérateurs de comparaison utilisent l’implémentation par défaut pour Variant, en appliquant la comparaison à chaque type de variante séparément. Ce comportement peut être désactivé à l’aide du paramètre use_variant_default_implementation_for_comparisons = 0 afin d’utiliser les règles de comparaison natives de Variant décrites ci-dessous. Remarque : ORDER BY utilise toujours la comparaison native. Règles de comparaison natives de Variant : Le résultat de l’opérateur < pour les valeurs v1 de type sous-jacent T1 et v2 de type sous-jacent T2 d’un type Variant(..., T1, ... T2, ...) est défini comme suit :
  • Si T1 = T2 = T, le résultat sera v1.T < v2.T (les valeurs sous-jacentes seront comparées).
  • Si T1 != T2, le résultat sera T1 < T2 (les noms de type seront comparés).
Exemples :
Si vous devez trouver la ligne contenant une valeur Variant spécifique, vous pouvez procéder de l’une des façons suivantes :
  • Convertir la valeur dans le type Variant correspondant :
  • Comparer la sous-colonne de Variant au type requis :
Il peut parfois être utile d’effectuer une vérification supplémentaire sur le type Variant, car les sous-colonnes ayant des types complexes comme Array/Map/Tuple ne peuvent pas être dans Nullable et auront des valeurs par défaut au lieu de NULL dans les lignes de types différents :
Note : les valeurs de Variant de types numériques différents sont considérées comme des Variant distincts et ne sont pas comparées entre elles ; ce sont leurs noms de type qui sont comparés à la place. Exemple :
Remarque : par défaut, le type Variant n’est pas autorisé dans les clés GROUP BY/ORDER BY ; si vous souhaitez l’utiliser, tenez compte de sa règle de comparaison particulière et activez les paramètres allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by.

Fonctions JSONExtract avec Variant

Toutes les fonctions JSONExtract* prennent en charge le type Variant :

Fonctions avec des arguments de type Variant

La plupart des fonctions de ClickHouse prennent automatiquement en charge les arguments de type Variant grâce à une implémentation par défaut pour Variant. À partir de la version 26.1, lorsqu’une fonction qui ne gère pas explicitement les types Variant reçoit une colonne Variant, ClickHouse :
  1. Extrait chaque type possible de la colonne Variant
  2. Exécute la fonction séparément pour chaque type possible
  3. Combine les résultats de manière appropriée selon leurs types
Cela vous permet d’utiliser des fonctions régulières avec des colonnes Variant sans traitement particulier. Exemple :
L’opérateur de comparaison est automatiquement appliqué séparément à chaque type de variante, ce qui permet de filtrer les colonnes Variant. Comportement du type de résultat : Le type de résultat dépend de ce que la fonction renvoie pour chaque variant :
  • Types de résultat différents : Variant(T1, T2, ...)
  • Incompatibilité de type : NULL pour les variants incompatibles
Gestion des erreurs : Lorsqu’une fonction ne peut pas traiter un type de variante, seules les erreurs liées au type (ILLEGAL_TYPE_OF_ARGUMENT, TYPE_MISMATCH, CANNOT_CONVERT_TYPE, NO_COMMON_TYPE) sont interceptées et donnent NULL pour ces lignes. Les autres erreurs, comme une division par zéro ou un manque de mémoire, sont levées normalement afin d’éviter de masquer silencieusement de vrais problèmes.

Comportement en cas d’incompatibilité de type

Le paramètre variant_throw_on_type_mismatch contrôle ce qui se passe lorsqu’une fonction est appliquée à une colonne Variant et que le type réellement stocké dans une ligne est incompatible avec cette fonction :
  • true (par défaut) — lève une exception (ILLEGAL_TYPE_OF_ARGUMENT) à la première ligne incompatible.
  • false — renvoie NULL pour les lignes incompatibles et conserve le résultat pour les lignes compatibles.
Exemple :
Dernière modification le 25 juin 2026