Variant(T1, T2, ..., TN) は、この型の各行が
T1 型、T2 型、…、TN 型のいずれか、またはいずれにも該当しない (NULL 値) 値を持つことを意味します。
ネストされた型の順序は重要ではありません: Variant(T1, T2) = Variant(T2, T1)。
ネストできる型は、Nullable(…)、LowCardinality(Nullable(…))、Variant(…) 型を除く任意の型です。
類似した型をバリアントとして使用することは推奨されません (たとえば、
Variant(UInt32, Int64) のような異なる数値型や、Variant(Date, DateTime) のような異なる日付型) 。
そのような型の値を扱うと曖昧さが生じる可能性があるためです。デフォルトでは、このような Variant 型を作成すると例外が発生しますが、設定 allow_suspicious_variant_types を使用すると有効にできます。Variant の作成
Variant 型を使用するには:
if/multiIf 関数を使用するには (この場合、設定 use_variant_as_common_type を有効にする必要があります) :
use_variant_as_common_type を有効にする必要があります) :
サブカラムとして Variant のネストされた型を読み取る
variant Variant(T1, T2, T3) というカラムがある場合、型 T2 のサブカラムは variant.T2 という構文で読み取れます。
このサブカラムの型は、T2 を Nullable に含められる場合は Nullable(T2)、そうでない場合は T2 になります。このサブカラムは
元の Variant カラムと同じサイズを持ち、元の Variant カラムが型 T2 ではないすべての行には NULL 値 (または T2 を Nullable に含められない場合は空の値)
が入ります。
Variant のサブカラムは、関数 variantElement(variant_column, type_name) を使って読み取ることもできます。
例:
variantType(variant_column) を使用できます。これは、各行の Variant 型の型名を表す Enum を返します (行が NULL の場合は 'None') 。
例:
Variant カラムと他のカラム間の変換
Variant 型のカラムに対しては、4 種類の変換を実行できます。
String カラムを Variant カラムに変換する
String から Variant への変換は、文字列値をパースして Variant 型の値に変換することで行われます。
String から Variant への変換時にパースを無効にするには、設定 cast_string_to_dynamic_use_inference をオフにします。
通常のカラムを Variant カラムに変換する
T の通常のカラムは、この型を持つ Variant カラムに変換できます。
String 型からの変換は常にパースを経由して行われます。パースせずに String カラムを Variant 型の String バリアントに変換する必要がある場合は、次のようにします:
Variant カラムを通常のカラムに変換する
Variant カラムは通常のカラムに変換できます。この場合、ネストされたすべての Variant の値は宛先の型に変換されます:
Variant を別の Variant に変換する
Variant カラムは別の Variant カラムに変換できますが、変換先の Variant カラムに元の Variant のすべてのネストされた型が含まれている場合に限ります。
データから Variant 型を読み取る
Variant 型の読み取りをサポートしています。データのパース時に、ClickHouse は値を最も適切な Variant 型として挿入しようとします。
例:
Variant 型の値の比較
Variant 型の値は、同じ Variant 型の値とのみ比較できます。
デフォルトでは、比較演算子は Variant のデフォルト実装 を使用し、
各 Variant 型ごとに個別に比較を行います。これは、設定 use_variant_default_implementation_for_comparisons = 0
を使用して無効にし、以下で説明するネイティブな Variant 比較ルールを使用できます。注: ORDER BY では常にネイティブ比較が使用されます。
ネイティブな Variant 比較ルール:
型 Variant(..., T1, ... T2, ...) において、内部の型 T1 を持つ値 v1 と、内部の型 T2 を持つ値 v2 に対する演算子 < の結果は、次のように定義されます。
T1 = T2 = Tの場合、結果はv1.T < v2.Tです (内部値が比較されます) 。T1 != T2の場合、結果はT1 < T2です (型名が比較されます) 。
Variant 値を持つ行を見つけるには、次のいずれかの方法を使用できます。
- 値を対応する
Variant型にキャストします。
Variantのサブカラムを必要な型と比較します:
Variant 型 を確認すると便利です。これは、Array/Map/Tuple のような複雑な型を持つサブカラムは Nullable に含めることができず、型が異なる行では NULL ではなくデフォルト値になるためです。
Variant 型は GROUP BY/ORDER BY キーでは使用できません。使用する場合は、その特殊な比較ルールを考慮したうえで、allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by 設定を有効にしてください。
Variant を引数に取る JSONExtract 関数
JSONExtract* 関数で Variant 型がサポートされています。
Variant 引数を持つ関数
Variant 型の引数を自動的にサポートします。
バージョン 26.1 以降では、Variant 型を明示的に処理しない関数に Variant カラムが渡されると、ClickHouse は次のように動作します。
- Variant カラムから各 Variant 型を抽出する
- 各 Variant 型ごとに関数を個別に実行する
- 結果の型に応じて適切に結果をまとめる
-
結果型が異なる場合:
Variant(T1, T2, ...) -
型に互換性がない場合: 互換性のない Variant では
NULL
エラー処理: 関数が Variant 型を処理できない場合、型関連のエラー (ILLEGAL_TYPE_OF_ARGUMENT,
TYPE_MISMATCH, CANNOT_CONVERT_TYPE, NO_COMMON_TYPE) のみが捕捉され、該当する行の結果は NULL になります。ゼロ除算やメモリ不足などのその他のエラーは、
実際の問題が見えなくならないよう、通常どおり送出されます。
型不一致時の動作
variant_throw_on_type_mismatch は、Variant カラムに関数を適用した際、その行に実際に格納されている型が関数と互換性がない場合の動作を制御します。
true(デフォルト) — 最初の非互換な行で例外 (ILLEGAL_TYPE_OF_ARGUMENT) をスローします。false— 非互換な行ではNULLを返し、互換性のある行については結果を返します。