Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

HiveText

Ввод Вывод Псевдоним

Описание

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_allow_variable_number_of_columns): в строках, где полей меньше, чем в таблице, отсутствующие столбцы заполняются значениями по умолчанию, а в строках с лишними конечными полями лишние поля пропускаются.

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

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

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

Дан файл hive_data.txt с полями, разделёнными запятыми:

hive_data.txttext
1,3
3,5,9

Мы создаём таблицу с именами столбцов и типами данных и вставляем в неё файл с помощью FORMAT HiveText:

Querysql
CREATE TABLE test_tbl (a UInt16, b UInt32, c UInt32) ENGINE = MergeTree ORDER BY a;

INSERT INTO test_tbl FROM INFILE 'hive_data.txt'
SETTINGS input_format_hive_text_fields_delimiter = ','
FORMAT HiveText;

SELECT * FROM test_tbl;
Responseresponse
┌─a─┬─b─┬─c─┐
│ 1 │ 3 │ 0 │
│ 3 │ 5 │ 9 │
└───┴───┴───┘

Обратите внимание, что первая строка 1,3 содержит только два поля, поэтому отсутствующий столбец c заполняется значением по умолчанию 0.

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

При значении по умолчанию input_format_hive_text_allow_variable_number_of_columns = 1 у строк, содержащих больше полей, чем предусмотрено в таблице, лишние поля в конце просто пропускаются:

hive_extras.txttext
1,2,3,4,5
6,7,8
Querysql
CREATE TABLE test_extras (a UInt16, b UInt32, c UInt32) ENGINE = MergeTree ORDER BY a;

INSERT INTO test_extras FROM INFILE 'hive_extras.txt'
SETTINGS input_format_hive_text_fields_delimiter = ','
FORMAT HiveText;

SELECT * FROM test_extras ORDER BY a;
Responseresponse
┌─a─┬─b─┬─c─┐
│ 1 │ 2 │ 3 │
│ 6 │ 7 │ 8 │
└───┴───┴───┘

Установка 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.

Querysql
SELECT '20240305', tuple(123567, 'e01001', map('action1', 33333, 'act2', 5555)) FORMAT HiveText;

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

Setting Description Default
input_format_hive_text_fields_delimiter Разделитель между полями в Hive Text File \x01
input_format_hive_text_collection_items_delimiter Разделитель между элементами коллекции (массива или map) в Hive Text File. Используется форматом вывода; принимается, но в настоящее время не используется при разборе. \x02
input_format_hive_text_map_keys_delimiter Разделитель между ключом и значением в map в Hive Text File. Используется форматом вывода; принимается, но в настоящее время не используется при разборе. \x03
input_format_hive_text_allow_variable_number_of_columns Игнорировать лишние столбцы во входных данных Hive Text (если в файле больше столбцов, чем ожидается) и использовать значения по умолчанию для отсутствующих полей 1
format_hive_text_rows_delimiter Разделитель в конце каждой строки в выводе Hive Text \n
Navigation