HiveText 형식

HiveText 형식

HiveText 형식은 Apache Hive 테이블이 사용하는 텍스트 직렬화 형식(Hive의 LazySimpleSerDe가 생성하는 형식)을 읽고 써요. CSV와 유사한 구분 텍스트 형식이며, 필드는 Hive 기본 \x01(Ctrl-A) 구분자로 구분됩니다. 필드 구분자는 input_format_hive_text_fields_delimiter로 설정할 수 있어요.

출처: 문서

본문

Input Output Alias

설명 (Description)

HiveText는 Apache Hive 테이블이 사용하는 텍스트 직렬화 형식(Hive의 LazySimpleSerDe가 생성하는 형식)을 읽고 씁니다. CSV와 유사한 구분 텍스트 형식이며, 필드는 Hive 기본 \x01(Ctrl-A) 구분자로 구분됩니다. 필드 구분자는 input_format_hive_text_fields_delimiter로 설정할 수 있어요.

입력 형식으로 사용하면 데이터에 헤더 행이 없습니다. 값은 대상 테이블의 컬럼에 위치적으로 매핑되므로, 컬럼 이름과 타입은 데이터에서 추론되지 않고 테이블(또는 명시적으로 제공된 구조)에서 가져옵니다. 읽는 동안 ClickHouse는 날짜와 시간을 best-effort 모드로 파싱하고( date_time_input_format 참조), 생략된 뒤따르는 필드를 컬럼 기본값으로 채우며, 인식하지 못하는 필드는 건너뜁니다.

필드 내에서 값은 Hive의 중첩 구분자 대신 CSV와 동일한 이스케이프 규칙으로 파싱됩니다. 특히 Array 타입의 컬럼은 Hive 컬렉션 구분자 \x02로 구분된 값이 아니라 괄호 표현(예: "['a','b','c']")에서 읽힙니다.

중첩 구분자 설정은 입력에 영향을 주지 않습니다. input_format_hive_text_collection_items_delimiter와 input_format_hive_text_map_keys_delimiter 설정은 호환성을 위해 허용되지만 현재 파싱 중에는 사용되지 않습니다. 그러나 출력 측에서 중첩 값을 쓸 때는 사용됩니다.

기본적으로 행은 가변적인 수의 필드를 가질 수 있습니다(input_format_hive_text_allow_variable_number_of_columns 참조): 테이블보다 필드가 적은 행은 누락된 컬럼이 기본값으로 채워지고, 뒤따르는 추가 필드가 있는 행은 추가분이 건너뜁니다.

사용 예시 (Example usage)

아래 예시들은 입력 파일을 읽기 쉽도록 input_format_hive_text_fields_delimiter를 사용하여 기본 필드 구분자를 쉼표(,)로 재정의합니다.

HiveText 파일 읽기 (Reading a HiveText file)

쉼표로 구분된 필드를 가진 hive_data.txt 파일이 있다고 가정해 볼게요:

hive_data.txt

1,3
3,5,9

컬럼 이름과 타입을 정의하는 테이블을 만들고 FORMAT HiveText로 파일을 삽입합니다:

쿼리

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;

응답

┌─a─┬─b─┬─c─┐
│ 1 │ 3 │ 0 │
│ 3 │ 5 │ 9 │
└───┴───┴───┘

첫 행 1,3은 필드가 두 개뿐이므로 누락된 컬럼 c가 기본값 0으로 채워진다는 점에 유의하세요.

가변 컬럼 수 (Variable number of columns)

기본 input_format_hive_text_allow_variable_number_of_columns = 1을 사용하면 테이블보다 필드가 많은 행은 뒤따르는 추가 필드만 건너뜁니다:

hive_extras.txt

1,2,3,4,5
6,7,8

쿼리

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;

응답

┌─a─┬─b─┬─c─┐
│ 1 │ 2 │ 3 │
│ 6 │ 7 │ 8 │
└───┴───┴───┘

대신 input_format_hive_text_allow_variable_number_of_columns = 0으로 설정하면 엄격한 필드 수를 강제하고, 테이블보다 필드가 적은 행은 파싱 예외를 발생시킵니다.

출력 (Output)

출력 형식으로 사용하면 HiveText는 각 행을 따옴표 없이 씁니다. 최상위 필드는 필드 구분자(기본 \x01)로 구분되고 행은 행 구분자(기본 \n, format_hive_text_rows_delimiter로 설정 가능)로 구분됩니다. 중첩 타입(Array, Map, Tuple)의 값은 괄호 없이 기록되며, Hive의 LazySimpleSerDe가 하는 것처럼 해당 중첩 수준에 대한 Hive 구분자로 구분됩니다. 처음 세 구분자는 설정 가능한 필드 구분자, input_format_hive_text_collection_items_delimiter(기본 \x02, 배열 요소, 맵 항목, 튜플 요소에 사용), input_format_hive_text_map_keys_delimiter(기본 \x03, 맵 키와 값 사이에 사용)입니다. 더 깊은 수준은 연속된 제어 문자(기본 \x04, \x05 등, 최대 8수준)입니다. 8수준을 넘는 구분자가 필요할 만큼 깊게 중첩된 타입 트리는 NOT_IMPLEMENTED 예외로 거부됩니다. Hive의 LazySimpleSerDe에도 그에 대한 구분자가 없기 때문입니다.

자연스러운 Hive 텍스트 표현이 없는 데이터 타입은 출력에서 지원되지 않으며 NOT_IMPLEMENTED 예외를 발생시킵니다. 여기에는 AggregateFunction, Dynamic, Variant, LowCardinality, Object와 숫자 지원 타입 Enum, Time, Time64, Interval이 포함됩니다 — 후자는 Hive에 일치하는 타입이 없으므로 원시 기본 숫자로 쓰는 대신 거부됩니다.

넓은 숫자 타입 Int128, UInt128, Int256, UInt256도 같은 이유로 거부됩니다. 가장 넓은 Hive 정수는 BIGINT(64비트)이고, Hive DECIMAL의 최대 정밀도 38조차 그 값 범위를 담을 수 없습니다. 마찬가지로 정밀도가 38을 넘는(즉 Decimal256) Decimal 값은 Hive DECIMAL의 최대 정밀도를 초과하므로 거부됩니다.

또한 Map 키는 기본 타입이어야 합니다. Hive는 MAP<primitive_type, data_type>으로 맵을 선언하므로, 키 타입이 Array, Map 또는 Tuple(ClickHouse가 허용하는)인 Map은 어떤 Hive 스키마도 그러한 값을 다시 읽을 수 없기 때문에 NOT_IMPLEMENTED 예외로 거부됩니다. 빈 맵 리터럴 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 설정과 무관합니다. 따라서 해당 설정이 unix_timestamp 또는 iso여도 출력이 Hive에서 파싱 가능하게 유지됩니다.

같은 이유로 Bool 값은 bool_true_representation 및 bool_false_representation 설정과 무관하게 항상 true/false로 기록되고, NULL 값은 format_csv_null_representation 설정과 무관하게 항상 Hive의 기본 null 시퀀스 \N으로 기록됩니다. 이렇게 하면 이러한 일반 텍스트 설정과 관계없이 출력이 Hive의 LazySimpleSerDe로 읽을 수 있게 유지됩니다. 대칭적으로 HiveText 입력 형식은 format_csv_null_representation 설정과 무관하게 항상 \N을 NULL로 읽으므로 최상위 스칼라 왕복은 그 설정에 의존하지 않습니다.

Non-finite Float32, Float64 값은 ClickHouse의 일반적인 nan/inf/-inf 토큰 대신 Hive의 Java 철자인 NaN, Infinity, -Infinity로 기록되므로, Hive의 FLOAT/DOUBLE 파서가 그것을 NULL이 아닌 같은 값으로 다시 읽어들입니다.

Hive 호환 출력, 입력 형식을 통한 완전한 왕복은 아님 (Hive-compatible output, not a full round-trip through the input format)

출력 측은 Hive의 기본 LazySimpleSerDe를 대상으로 하며 ClickHouse 자체의 HiveText 입력과 대칭이 아닙니다:

  • 중첩 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로 동작하는 방식과 일치합니다. 같은 이유로 값이 문자 그대로 \NString(예: SELECT '\\N'::String FORMAT HiveText)은 실제 NULL과 같은 두 바이트로 기록되어, Hive 쪽에서 둘을 구분할 수 없습니다.

쿼리

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

형식 설정 (Format settings)

Setting Description Default
input_format_hive_text_fields_delimiter Hive Text File에서 필드 사이의 구분자 \x01
input_format_hive_text_collection_items_delimiter Hive Text File에서 컬렉션(배열 또는 맵) 항목 사이의 구분자. 출력 형식에 사용되며 허용되지만 현재 입력 파싱 중에는 사용되지 않음. \x02
input_format_hive_text_map_keys_delimiter Hive Text File에서 맵 키/값 쌍 사이의 구분자. 출력 형식에 사용되며 허용되지만 현재 입력 파싱 중에는 사용되지 않음. \x03
input_format_hive_text_allow_variable_number_of_columns Hive Text 입력에서 추가 컬럼 무시(파일이 예상보다 많은 컬럼) 및 누락 필드를 기본값으로 처리 1
format_hive_text_rows_delimiter Hive Text 출력에서 각 행 끝의 구분자 \n

더 알아보기 (Learn more)