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.
Этот подстолбец будет иметь тип Nullable(T2), если T2 может находиться внутри Nullable, и тип T2 в противном случае. Размер этого подстолбца будет
таким же, как у исходного столбца Variant, и он будет содержать значения NULL (или пустые значения, если T2 не может находиться внутри Nullable)
во всех строках, в которых исходный столбец Variant не имеет тип T2.
Подстолбцы Variant также можно читать с помощью функции variantElement(variant_column, type_name).
Примеры:
variantType(variant_column). Она возвращает Enum с именем типа варианта для каждой строки (или 'None', если строка имеет значение NULL).
Пример:
Преобразование между столбцом Variant и другими столбцами
Variant.
Преобразование столбца String в столбец Variant
String в Variant выполняется путём синтаксического разбора строкового значения как значения типа Variant:
String в Variant, можно отключить настройку cast_string_to_dynamic_use_inference:
Преобразование обычного столбца в столбец типа Variant
T можно преобразовать в столбец Variant, содержащий этот тип:
String всегда выполняется через разбор; если вам нужно преобразовать столбец String в вариант String типа Variant без разбора, можно сделать следующее:
Преобразование столбца Variant в обычный столбец
Variant можно преобразовать в обычный столбец. В этом случае все вложенные варианты будут преобразованы в целевой тип:
Преобразование Variant в другой Variant
Variant в другой столбец Variant, но только если целевой столбец Variant содержит все вложенные типы исходного Variant:
Чтение типа Variant из данных
Variant. При разборе данных ClickHouse пытается вставить значение в наиболее подходящий тип варианта.
Пример:
Сравнение значений типа Variant
Variant можно сравнивать только со значениями того же типа Variant.
По умолчанию операторы сравнения используют реализацию по умолчанию для Variant,
выполняя сравнение отдельно для каждого типа варианта. Это поведение можно отключить настройкой use_variant_default_implementation_for_comparisons = 0,
чтобы использовать нативные правила сравнения Variant, описанные ниже. Обратите внимание, что ORDER BY всегда использует нативное сравнение.
Нативные правила сравнения Variant:
Результат оператора < для значений v1 с базовым типом T1 и v2 с базовым типом T2 типа Variant(..., T1, ... T2, ...) определяется следующим образом:
- Если
T1 = T2 = T, результатом будетv1.T < v2.T(будут сравниваться внутренние значения). - Если
T1 != T2, результатом будетT1 < T2(будут сравниваться имена типов).
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.
Функции JSONExtract с аргументами типа Variant
JSONExtract* поддерживают тип Variant:
Функции с аргументами Variant
Variant благодаря реализации по умолчанию для Variant.
Начиная с версии 26.1, если функция, которая не обрабатывает типы Variant явно, получает столбец Variant, ClickHouse:
- Извлекает каждый тип варианта из столбца Variant
- Выполняет функцию отдельно для каждого типа варианта
- Объединяет результаты с учётом их типов
-
Разные результирующие типы:
Variant(T1, T2, ...) -
Несовместимость типов:
NULLдля несовместимых вариантов
Обработка ошибок: Если функция не может обработать тип варианта, перехватываются только ошибки, связанные с типами (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для несовместимых строк и сохранять результат для совместимых строк.