설명
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와 동일한 이스케이프 규칙으로
파싱됩니다. 특히,
배열 타입의 컬럼은 대괄호로 묶인
표현(예: "['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를 통해 구성 가능)로 구분됩니다. 중첩 타입 값
(배열, 맵
및 Tuple)은 대괄호 없이 작성되며,
Hive의 LazySimpleSerDe와 마찬가지로 중첩 수준에 해당하는 Hive 구분자로
구분됩니다. 처음 세 구분자는 구성 가능한 필드
구분자, input_format_hive_text_collection_items_delimiter
(기본값: \x02, 배열 원소, 맵 항목 및 튜플 원소에 사용) 및
input_format_hive_text_map_keys_delimiter(기본값: \x03,
맵 키와 값 사이에 사용)이며, 더 깊은 수준에서는 연속된 제어
문자(\x04, \x05 등, 최대 8개 수준까지)가 기본값으로 사용됩니다. 이 8개 수준을
넘는 구분자가 필요할 정도로 깊이 중첩된 타입 트리는
Hive의 LazySimpleSerDe에도 해당 구분자가 없으므로 NOT_IMPLEMENTED 예외와 함께 거부됩니다. 자연스러운
Hive 텍스트 표현이 없는 데이터 타입은 출력에 지원되지 않으며
NOT_IMPLEMENTED 예외를 발생시킵니다. 여기에는 AggregateFunction, Dynamic,
Variant, LowCardinality, Object와 숫자를 기반으로 하는 타입인
Enum, Time, Time64, Interval이 포함됩니다. 후자에 대응하는 Hive 타입이
없으므로 원시 기반 숫자로 작성하지 않고 거부됩니다.
와이드 숫자 타입인 Int128, UInt128, Int256, UInt256도
같은 이유로 거부됩니다. 가장 넓은 Hive 정수 타입은 BIGINT(64비트)이고,
최대 정밀도가 38인 Hive DECIMAL조차 이들의 값 범위를 저장할 수 없기 때문입니다.
마찬가지로 정밀도가 38을 초과하는 Decimal 값(즉,
Decimal256)은 Hive DECIMAL의 최대 정밀도를 초과하므로 거부됩니다.
또한 맵 키는 기본 타입이어야 합니다. Hive는 맵을
MAP<primitive_type, data_type>로 선언하므로 키 타입이 Array,
Map 또는 Tuple인 Map(ClickHouse에서는 허용됨)은
NOT_IMPLEMENTED 예외와 함께 거부됩니다. 이러한 값을 다시 읽을 수 있는 Hive 스키마가
없기 때문입니다. 빈 맵 리터럴 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 값은 항상 true/false로 작성되며,
bool_true_representation
및 bool_false_representation
설정과 무관합니다. 또한 NULL 값은 항상 Hive의 기본 null 시퀀스인
\N으로 작성되며, format_csv_null_representation
설정과 무관합니다. 이렇게 하면 이러한 일반 텍스트 설정과 관계없이 출력이 Hive의 LazySimpleSerDe에서
읽을 수 있도록 유지됩니다. 마찬가지로 HiveText 입력 형식은 항상
\N을 NULL로 읽으며, 이 역시
format_csv_null_representation
설정과 무관하므로 최상위 스칼라 왕복은 이 설정에 의존하지 않습니다.
유한하지 않은 Float32 및 Float64 값은 ClickHouse에서 일반적으로 사용하는 nan/inf/-inf
토큰 대신 Hive의 Java 표기법인 NaN, Infinity, -Infinity를 사용해 기록됩니다.
이렇게 하면 Hive의 FLOAT/DOUBLE 파서가 이를 NULL이 아닌 원래 값으로 다시
읽습니다.
Hive 호환 출력이며, 입력 형식을 통한 완전한 왕복은 지원하지 않습니다출력 측은 Hive의 기본
LazySimpleSerDe를 대상으로 하며,
ClickHouse 자체의 HiveText 입력과 대칭적이지 않습니다.- 중첩된
배열,맵및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에서 3개의 행으로 다시 읽히지 않습니다. - 기본 이스케이프 없는
LazySimpleSerDe부분 집합만 구현됩니다. 필드는 이스케이프 없이 기록되며(Hive의 선택적ROW FORMAT DELIMITED ... ESCAPED BY에 해당하는 기능은 없음),NULL은 항상\N으로 기록됩니다(NULL DEFINED AS에 해당하는 기능은 없음). 따라서 활성 필드, 행 또는 중첩 구분자를 포함하는String은 그대로 기록되며, 다시 파싱하면 잘못 읽힙니다. 이는 이스케이프하지 않는 serde에서 Hive 자체가 동작하는 방식과 같습니다. 같은 이유로 값이 문자 그대로\N인String(예:SELECT '\\N'::String FORMAT HiveText)은 실제NULL과 동일한 두 바이트로 기록되므로 Hive 측에서는 둘을 구별할 수 없습니다.
Query