> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Документация по формату HiveText

# HiveText

| Ввод | Вывод | Псевдоним |
| ---- | ----- | --------- |
| ✔    | ✔     |           |

<div id="description">
  ## Описание
</div>

`HiveText` читает и записывает формат текстовой сериализации, используемый таблицами
[Apache Hive](https://hive.apache.org/) (формат, создаваемый `LazySimpleSerDe`
в Hive). Это текстовый формат с разделителями, похожий на [`CSV`](/docs/ru/reference/formats/CSV/CSV), в котором поля
разделяются стандартным для Hive разделителем `\x01` (Ctrl-A). Разделитель полей
можно настроить через [`input_format_hive_text_fields_delimiter`](#format-settings).

При использовании в качестве входного формата у данных нет строки заголовка: значения
сопоставляются со столбцами целевой таблицы по позиции, поэтому имена столбцов и типы
берутся из таблицы (или из явно заданной
структуры), а не определяются автоматически по данным. При чтении ClickHouse разбирает
даты и время в режиме best-effort (см. [`date_time_input_format`](/docs/ru/reference/settings/formats/date-time#date_time_input_format)),
заполняет пропущенные конечные поля значениями по умолчанию для столбцов и пропускает поля, которые не
распознаёт.

Внутри поля значения разбираются по тем же правилам экранирования, что и в `CSV`, а не
с использованием вложенных разделителей Hive. В частности, столбец типа
[`Array`](/docs/ru/reference/data-types/array) читается из представления
в квадратных скобках (например, `"['a','b','c']"`), а не из значений, разделённых
разделителем коллекции Hive `\x02`.

<Info>
  **Настройки вложенных разделителей не влияют на ввод**

  Настройки [`input_format_hive_text_collection_items_delimiter`](#format-settings) и
  [`input_format_hive_text_map_keys_delimiter`](#format-settings)
  принимаются для совместимости, но в настоящее время не используются при разборе. Однако
  они используются при записи вложенных значений.
</Info>

По умолчанию строкам разрешено иметь переменное число полей (см.
[`input_format_hive_text_allow_variable_number_of_columns`](#format-settings)):
в строках, где полей меньше, чем в таблице, отсутствующие столбцы заполняются
значениями по умолчанию, а в строках с лишними конечными полями лишние поля пропускаются.

<div id="example-usage">
  ## Пример использования
</div>

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

<div id="reading-data">
  ### Чтение файла в формате HiveText
</div>

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

```text title="hive_data.txt" theme={null}
1,3
3,5,9
```

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

```sql title="Query" theme={null}
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;
```

```response title="Response" theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 3 │ 0 │
│ 3 │ 5 │ 9 │
└───┴───┴───┘
```

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

<div id="variable-number-of-columns">
  ### Переменное количество столбцов
</div>

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

```text title="hive_extras.txt" theme={null}
1,2,3,4,5
6,7,8
```

```sql title="Query" theme={null}
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;
```

```response title="Response" theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 2 │ 3 │
│ 6 │ 7 │ 8 │
└───┴───┴───┘
```

Установка `input_format_hive_text_allow_variable_number_of_columns = 0` вместо этого
требует строгого количества полей, и если в строке полей меньше, чем в таблице, возникает
исключение при разборе.

<div id="output">
  ## Вывод
</div>

При использовании в качестве выходного формата `HiveText` записывает каждую строку без экранирования:
поля верхнего уровня разделяются разделителем полей (по умолчанию `\x01`), а
строки — разделителем строк (по умолчанию `\n`, настраивается с помощью
[`format_hive_text_rows_delimiter`](#format-settings)). Значения вложенных типов
([`Array`](/docs/ru/reference/data-types/array), [`Map`](/docs/ru/reference/data-types/map)
и [`Tuple`](/docs/ru/reference/data-types/tuple)) записываются без скобок и
разделяются разделителем Hive соответствующего уровня вложенности — так же, как в
`LazySimpleSerDe` Hive. Первые три разделителя: настраиваемый разделитель
полей, [`input_format_hive_text_collection_items_delimiter`](#format-settings)
(по умолчанию `\x02`, используется для элементов массива, записей map и элементов кортежа) и
[`input_format_hive_text_map_keys_delimiter`](#format-settings) (по умолчанию `\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`](/docs/ru/reference/settings/formats/date-time#date_time_output_format),
чтобы вывод оставался доступным для разбора в Hive, даже если эта настройка имеет значение
`unix_timestamp` или `iso`.

По той же причине значения `Bool` всегда записываются как `true`/`false`,
независимо от настроек [`bool_true_representation`](/docs/ru/reference/settings/formats/bool#bool_true_representation)
и [`bool_false_representation`](/docs/ru/reference/settings/formats/bool#bool_false_representation),
а значения `NULL` всегда записываются как используемая Hive по умолчанию null-последовательность
`\N`, независимо от настройки [`format_csv_null_representation`](/docs/ru/reference/settings/formats/format-csv#format_csv_null_representation).
Благодаря этому вывод остаётся читаемым для `LazySimpleSerDe` Hive независимо от
этих общих текстовых настроек. Аналогично, входной формат `HiveText` всегда
интерпретирует `\N` как `NULL`, также независимо от настройки
[`format_csv_null_representation`](/docs/ru/reference/settings/formats/format-csv#format_csv_null_representation),
поэтому цикл записи и чтения скаляров верхнего уровня от неё не зависит.

Неконечные значения `Float32` и `Float64` записываются с использованием Java-обозначений Hive
`NaN`, `Infinity` и `-Infinity`, а не обычных для ClickHouse токенов `nan`/`inf`/`-inf`,
чтобы парсер Hive для `FLOAT`/`DOUBLE` считывал их как те же значения,
а не как `NULL`.

<Info>
  **Вывод, совместимый с Hive, а не полноценный цикл записи и чтения через входной формат**

  Вывод ориентирован на используемый в Hive по умолчанию `LazySimpleSerDe` и не симметричен
  собственному входному формату `HiveText` ClickHouse:

  * Вложенные значения [`Array`](/docs/ru/reference/data-types/array), [`Map`](/docs/ru/reference/data-types/map)
    и [`Tuple`](/docs/ru/reference/data-types/tuple) записываются с использованием вложенных
    разделителей Hive (без скобок), но входной формат разбирает каждое поле по правилам
    `CSV`/со скобками и игнорирует
    [`input_format_hive_text_collection_items_delimiter`](#format-settings) /
    [`input_format_hive_text_map_keys_delimiter`](#format-settings). Поэтому вложенный вывод,
    например `SELECT [1, 2] FORMAT HiveText`, **не** считывается обратно с помощью
    `INSERT ... FORMAT HiveText` — цикл записи и чтения поддерживается только для скалярных полей верхнего уровня
    и только с разделителем строк по умолчанию `\n` (см. следующий пункт).
  * Для цикла записи и чтения также требуется разделитель строк по умолчанию `\n`. При изменении
    [`format_hive_text_rows_delimiter`](#format-settings) вывод разделяет
    строки настроенным байтом, но на входе по-прежнему используется `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 их невозможно различить.
</Info>

```sql title="Query" theme={null}
SELECT '20240305', tuple(123567, 'e01001', map('action1', 33333, 'act2', 5555)) FORMAT HiveText;
```

<div id="format-settings">
  ## Настройки формата
</div>

| 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`    |
