Skip to main content

Описание

HiveText читает и записывает формат текстовой сериализации, используемый таблицами Apache Hive (формат, создаваемый LazySimpleSerDe в Hive). Это текстовый формат с разделителями, похожий на CSV, в котором поля разделяются стандартным для Hive разделителем \x01 (Ctrl-A). Разделитель полей можно настроить через input_format_hive_text_fields_delimiter. При использовании в качестве входного формата у данных нет строки заголовка: значения сопоставляются со столбцами целевой таблицы по позиции, поэтому имена столбцов и типы берутся из таблицы (или из явно заданной структуры), а не определяются автоматически по данным. При чтении ClickHouse разбирает даты и время в режиме best-effort (см. date_time_input_format), заполняет пропущенные конечные поля значениями по умолчанию для столбцов и пропускает поля, которые не распознаёт. Внутри поля значения разбираются по тем же правилам экранирования, что и в CSV, а не с использованием вложенных разделителей Hive. В частности, столбец типа Array читается из представления в квадратных скобках (например, "['a','b','c']"), а не из значений, разделённых разделителем коллекции Hive \x02.
Настройки вложенных разделителей не влияют на вводНастройки input_format_hive_text_collection_items_delimiter и input_format_hive_text_map_keys_delimiter принимаются для совместимости, но в настоящее время не используются при разборе. Однако они используются при записи вложенных значений.
По умолчанию строкам разрешено иметь переменное число полей (см. input_format_hive_text_allow_variable_number_of_columns): в строках, где полей меньше, чем в таблице, отсутствующие столбцы заполняются значениями по умолчанию, а в строках с лишними конечными полями лишние поля пропускаются.

Пример использования

В приведённых ниже примерах разделитель полей по умолчанию заменён на запятую (,) с помощью input_format_hive_text_fields_delimiter, чтобы входные файлы было удобнее читать.

Чтение файла в формате HiveText

Дан файл hive_data.txt с полями, разделёнными запятыми:
hive_data.txt
Мы создаём таблицу с именами столбцов и типами данных и вставляем в неё файл с помощью FORMAT HiveText:
Query
Response
Обратите внимание, что первая строка 1,3 содержит только два поля, поэтому отсутствующий столбец c заполняется значением по умолчанию 0.

Переменное количество столбцов

При значении по умолчанию input_format_hive_text_allow_variable_number_of_columns = 1 у строк, содержащих больше полей, чем предусмотрено в таблице, лишние поля в конце просто пропускаются:
hive_extras.txt
Query
Response
Установка input_format_hive_text_allow_variable_number_of_columns = 0 вместо этого требует строгого количества полей, и если в строке полей меньше, чем в таблице, возникает исключение при разборе.

Вывод

При использовании в качестве выходного формата HiveText записывает каждую строку без экранирования: поля верхнего уровня разделяются разделителем полей (по умолчанию \x01), а строки — разделителем строк (по умолчанию \n, настраивается с помощью format_hive_text_rows_delimiter). Значения вложенных типов (Array, Map и Tuple) записываются без скобок и разделяются разделителем Hive соответствующего уровня вложенности — так же, как в LazySimpleSerDe Hive. Первые три разделителя: настраиваемый разделитель полей, input_format_hive_text_collection_items_delimiter (по умолчанию \x02, используется для элементов массива, записей map и элементов кортежа) и input_format_hive_text_map_keys_delimiter (по умолчанию \x03, используется между ключом map и его значением); для более глубоких уровней по умолчанию используются последовательные управляющие символы (\x04, \x05 и так далее, до восьми уровней). Дерево типов с достаточно глубокой вложенностью, которому требуется разделитель за пределами этих восьми уровней, отклоняется с исключением NOT_IMPLEMENTED, поскольку в LazySimpleSerDe Hive также нет разделителя для него. Типы данных, не имеющие естественного текстового представления в Hive, не поддерживаются для вывода и вызывают исключение NOT_IMPLEMENTED. К ним относятся AggregateFunction, Dynamic, Variant, LowCardinality и Object, а также числовые типы Enum, Time, Time64 и Interval — в Hive нет соответствующих типов для последних, поэтому они отклоняются, а не записываются как исходные базовые числа. Числовые типы большой разрядности Int128, UInt128, Int256 и UInt256 отклоняются по той же причине: самый широкий целочисленный тип Hive — BIGINT (64-битный), и даже DECIMAL Hive с максимальной точностью 38 не может вместить весь их диапазон значений. Аналогично, значения Decimal с точностью выше 38 (то есть Decimal256) превышают максимальную точность DECIMAL Hive и отклоняются. Также ключи Map должны иметь примитивный тип: Hive объявляет map как MAP<primitive_type, data_type>, поэтому Map с типом ключа Array, Map или Tuple (что допускает ClickHouse) отклоняется с исключением NOT_IMPLEMENTED, поскольку ни одна схема Hive не смогла бы прочитать такие значения обратно. Пустой литерал map map() отклоняется по той же причине: его тип — Map(Nothing, Nothing), а Nothing не является типом, который мог бы быть указан в объявлении Hive MAP<key_type, data_type>. Все эти проверки применяются заранее к объявленным типам столбцов, до записи любой строки: запрос, заголовок которого содержит неподдерживаемый тип в любом месте дерева типов, отклоняется, даже если фактические значения никогда не достигли бы неподдерживаемой сериализации (например, Nullable неподдерживаемого типа, содержащий только значения NULL, или пустой Array/Map с неподдерживаемым типом элемента), поскольку объявленная схема файла всё равно не могла бы соответствовать ни одной таблице Hive. Date, Date32, DateTime и DateTime64 всегда записываются в обычном текстовом формате даты и временной метки Hive (yyyy-MM-dd и yyyy-MM-dd HH:mm:ss[.fffffffff]), независимо от настройки date_time_output_format, чтобы вывод оставался доступным для разбора в Hive, даже если эта настройка имеет значение unix_timestamp или iso. По той же причине значения Bool всегда записываются как true/false, независимо от настроек bool_true_representation и bool_false_representation, а значения NULL всегда записываются как используемая Hive по умолчанию null-последовательность \N, независимо от настройки format_csv_null_representation. Благодаря этому вывод остаётся читаемым для LazySimpleSerDe Hive независимо от этих общих текстовых настроек. Аналогично, входной формат HiveText всегда интерпретирует \N как NULL, также независимо от настройки format_csv_null_representation, поэтому цикл записи и чтения скаляров верхнего уровня от неё не зависит. Неконечные значения Float32 и Float64 записываются с использованием Java-обозначений Hive NaN, Infinity и -Infinity, а не обычных для ClickHouse токенов nan/inf/-inf, чтобы парсер Hive для FLOAT/DOUBLE считывал их как те же значения, а не как NULL.
Вывод, совместимый с Hive, а не полноценный цикл записи и чтения через входной форматВывод ориентирован на используемый в Hive по умолчанию LazySimpleSerDe и не симметричен собственному входному формату HiveText ClickHouse:
  • Вложенные значения Array, Map и Tuple записываются с использованием вложенных разделителей Hive (без скобок), но входной формат разбирает каждое поле по правилам CSV/со скобками и игнорирует input_format_hive_text_collection_items_delimiter / input_format_hive_text_map_keys_delimiter. Поэтому вложенный вывод, например SELECT [1, 2] FORMAT HiveText, не считывается обратно с помощью INSERT ... FORMAT HiveText — цикл записи и чтения поддерживается только для скалярных полей верхнего уровня и только с разделителем строк по умолчанию \n (см. следующий пункт).
  • Для цикла записи и чтения также требуется разделитель строк по умолчанию \n. При изменении format_hive_text_rows_delimiter вывод разделяет строки настроенным байтом, но на входе по-прежнему используется CSVRowInputFormat, основанный на переводах строк, и соответствующий параметр input_format_hive_text_rows_delimiter отсутствует. Поэтому многострочный скалярный вывод, например SELECT number FROM numbers(3) FORMAT HiveText SETTINGS format_hive_text_rows_delimiter=';' (который создаёт 0;1;2;), не считывается обратно через INSERT ... FORMAT HiveText как три строки.
  • Реализовано только используемое по умолчанию подмножество LazySimpleSerDe без экранирования. Поля записываются без экранирования (нет эквивалента необязательного параметра Hive ROW FORMAT DELIMITED ... ESCAPED BY), а NULL всегда записывается как \N (нет эквивалента NULL DEFINED AS). Поэтому String, содержащая активный разделитель поля, строки или вложенных значений, записывается буквально и при последующем разборе будет прочитана неверно — это соответствует поведению самого Hive с serde без экранирования. По той же причине String, значение которой буквально равно \N (например, SELECT '\\N'::String FORMAT HiveText), записывается теми же двумя байтами, что и настоящий NULL, поэтому на стороне Hive их невозможно различить.
Query

Настройки формата

Последнее изменение 14 августа 2026 г.