> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8c05c8a2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Native 형식 문서

# Native

| 입력 | 출력 | 별칭 |
| -- | -- | -- |
| ✔  | ✔  |    |

<div id="description">
  ## 설명
</div>

`Native` 형식의 전체 공식 명세는 [여기](/ko/reference/interfaces/specs/NativeFormat)에서 확인할 수 있으며, 이를 전달하는 TCP wire 프로토콜인 `Native` 프로토콜의 보완 명세는 [여기](/ko/reference/interfaces/specs/NativeProtocol)에서 확인할 수 있습니다.

<Note>
  두 명세는 모두 ClickHouse 소스 코드를 바탕으로 LLM이 생성했습니다. 코드는 여전히 가장 중요한 기준입니다. 명세와 코드가 일치하지 않으면 코드가 올바릅니다.
</Note>

`Native` 형식은 컬럼을 행으로 변환하지 않는 진정한 "열 지향" 포맷이므로 ClickHouse에서 가장 효율적인 포맷입니다.

이 포맷에서는 데이터가 바이너리 형식으로 [블록](/ko/resources/develop-contribute/introduction/architecture#block) 단위로 기록되고 읽힙니다.
각 블록에는 행 수, 컬럼 수, 컬럼 이름과 타입, 그리고 블록 내 각 컬럼 데이터의 일부가 차례대로 기록됩니다.

이 포맷은 서버 간 상호작용을 위한 네이티브 인터페이스, command-line client 사용, 그리고 C++ 클라이언트에서 사용됩니다.

<Tip>
  이 포맷을 사용하면 ClickHouse DBMS에서만 읽을 수 있는 덤프를 빠르게 생성할 수 있습니다.
  다만 이 포맷을 직접 다루는 것은 실용적이지 않을 수 있습니다.
</Tip>

<div id="data-types-wire-format">
  ## 데이터 타입 wire 형식
</div>

데이터는 wire 상에서 열 지향 포맷으로 전송되며, 이는 각 컬럼이 개별적으로 전송되고
한 컬럼의 모든 값이 하나의 배열로 함께 전송된다는 뜻입니다.

블록의 각 컬럼에는 [RowBinaryWithNamesAndTypes](/ko/reference/formats/RowBinary/RowBinaryWithNamesAndTypes)와 유사한 헤더가 포함됩니다.

<Note>
  네이티브 TCP 바이너리 프로토콜을 사용하거나(또는 HTTP 엔드포인트가 `?client_protocol_version=<n>`을 받을 때),
  컬럼 수와 행 수 앞에 `BlockInfo` 구조체가 기록됩니다. 이 섹션의 예시는
  프로토콜 버전이 없는 일반 HTTP 인터페이스를 사용하므로 `BlockInfo`는 생략됩니다.
</Note>

<div id="block-structure">
  ### 블록 구조
</div>

다음 쿼리는 `number`와 `str` 두 개의 컬럼과 3개의 행을 반환합니다:

```bash theme={null}
curl -XPOST "http://localhost:8123?default_format=Native" --data-binary "SELECT number, toString(number) AS str FROM system.numbers LIMIT 3" > out.bin
```

출력 데이터는 하나의 ClickHouse 블록에 들어가며, 다음과 같습니다:

```js theme={null}
const data = new Uint8Array([
  // --- 블록 헤더 ---
  0x02,                   // 컬럼 2개
  0x03,                   // 행 3개
  // -- 컬럼 1 헤더 --
  0x06,                   // LEB128 - 컬럼명 'number'는 6바이트
  0x6e, 0x75, 0x6d,       
  0x62, 0x65, 0x72,       // 컬럼명: 'number'
  0x06,                   // LEB128 - 컬럼 타입 'UInt64'는 6바이트
  0x55, 0x49, 0x6e,
  0x74, 0x36, 0x34,       // 'UInt64'
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, // UInt64 값 0
  0x01, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, // UInt64 값 1
  0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, // UInt64 값 2
  0x03,                   // LEB128 - 컬럼명 'str'는 3바이트
  0x73, 0x74, 0x72,       // 컬럼명: 'str'
  0x06,                   // LEB128 - 컬럼 타입 'String'는 6바이트
  0x53, 0x74, 0x72, 
  0x69, 0x6e, 0x67,       // 'String'
  0x01,                   // LEB128 - 문자열 길이 1바이트
  0x30,                   // String 값 '0'
  0x01,                   // LEB128 - 문자열 길이 1바이트
  0x31,                   // String 값 '1'
  0x01,                   // LEB128 - 문자열 길이 1바이트
  0x32,                   // String 값 '2'
])
```

<div id="multiple-blocks">
  ### 여러 블록
</div>

하지만 많은 경우 데이터가 단일 블록 하나에 담기지 않으므로, ClickHouse는 데이터를 여러 블록으로 나누어 전송합니다.
다음 쿼리는 블록 크기를 줄여 데이터가 블록당 한 행씩 분할되도록 강제한 상태에서 2개의 행을 가져오는 예입니다:

```bash theme={null}
curl -XPOST "http://localhost:8123?default_format=Native" --data-binary "SELECT number, toString(number) AS str                FROM system.numbers LIMIT 2                 SETTINGS max_block_size=1" \  > out.bin
```

출력 결과:

```js theme={null}
const data = new Uint8Array([
 
  // ----- 블록 1 ----- 
  0x02,                   // 컬럼 2개
  0x01,                   // 행 1개
  0x06,                   // LEB128 - 컬럼명 'number'는 6바이트
  0x6E, 0x75, 0x6D, 
  0x62, 0x65, 0x72,       // 컬럼명: 'number' 
  0x06,                   // LEB128 - 컬럼 유형 'UInt64'는 6바이트
  0x55, 0x49, 0x6E, 
  0x74, 0x36, 0x34,       // 'UInt64' 
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, // UInt64로 표현한 0
  0x03,                   // LEB128 - 컬럼명 'str'는 3바이트
  0x73, 0x74, 0x72,       // 컬럼명: 'str'
  0x06,                   // LEB128 - 컬럼 유형 'String'은 6바이트
  0x53, 0x74, 0x72, 
  0x69, 0x6E, 0x67,       // 'String'
  0x01,                   // LEB128 - 문자열은 1바이트
  0x30,                   // String으로 표현한 '0'
  
  // ----- 블록 2 -----
  0x02,                   // 컬럼 2개
  0x01,                   // 행 1개
  0x06,                   // LEB128 - 컬럼명 'number'는 6바이트
  0x6E, 0x75, 0x6D,  
  0x62, 0x65, 0x72,       // 컬럼명: 'number'
  0x06,                   // LEB128 - 컬럼 유형 'UInt64'는 6바이트
  0x55, 0x49, 0x6E,  
  0x74, 0x36, 0x34,       // 'UInt64'
  0x01, 0x00, 0x00, 0x00,  
  0x00, 0x00, 0x00, 0x00, // UInt64로 표현한 1
  0x03,                   // LEB128 - 컬럼명 'str'는 3바이트
  0x73, 0x74, 0x72,       // 컬럼명: 'str'
  0x06,                   // LEB128 - 컬럼 유형 'String'은 6바이트
  0x53, 0x74, 0x72,  
  0x69, 0x6E, 0x67,       // 'String'
  0x01,                   // LEB128 - 문자열은 1바이트
  0x31,                   // String으로 표현한 '1'
]);
```

<div id="simple-data-types">
  ### 단순 데이터 타입
</div>

보다 단순한 데이터 타입에 속하는 개별 값의 wire 형식은 `RowBinary`/`RowBinaryWithNamesAndTypes`와 유사합니다.
이에 해당하는 전체 타입 목록은 다음과 같습니다.

* (U)Int8, (U)Int16, (U)Int32, (U)Int64, (U)Int128, (U)Int256
* Float32, Float64
* Bool
* String
* FixedString(N)
* Date
* Date32
* DateTime
* DateTime64
* IPv4
* IPv6
* UUID

자세한 내용은 ["RowBinary 데이터 타입의 wire 형식"](/ko/reference/formats/RowBinary/RowBinary#data-types-wire-format)에 있는 각 타입 설명을 참조하십시오.

<div id="complex-data-types">
  ### 복합 데이터 타입
</div>

다음 데이터 타입의 인코딩은 `RowBinary` 및 `RowBinaryWithNamesAndTypes`와 다릅니다.

* 널 허용
* LowCardinality
* 배열
* 맵
* Variant
* Dynamic
* JSON

<div id="nullable">
  #### 널 허용
</div>

`Native` 형식에서는 널 허용 컬럼의 실제 데이터 앞에 블록의 행 수와 동일한 바이트 수가 옵니다. 각 바이트는 해당 값이 `NULL`인지 여부를 나타냅니다. 예를 들어, 다음 쿼리에서는 각 홀수가 `NULL`이 됩니다:

```bash theme={null}
curl -XPOST "http://localhost:8123?default_format=Native" \  --data-binary "SELECT if(number % 2 = 0, number, NULL) :: Nullable(UInt64) AS maybe_null                 FROM system.numbers LIMIT 5" \  > out.bin
```

출력은 다음과 같은 형태입니다:

```js theme={null}
const data = new Uint8Array([
  // --- 블록 헤더 ---
  0x01,                         // LEB128 - 컬럼 1개
  0x05,                         // LEB128 - 행 5개
  
  // -- 컬럼 헤더 --
  0x0A,                         // LEB128 - 컬럼 이름 10바이트
  0x6D, 0x61, 0x79, 0x62, 0x65, 
  0x5F, 0x6E, 0x75, 0x6C, 0x6C, // 컬럼 이름: 'maybe_null'
  
  0x10,                         // LEB128 - 컬럼 유형 16바이트
  0x4E, 0x75, 0x6C, 0x6C, 
  0x61, 0x62, 0x6C, 0x65, 
  0x28, 0x55, 0x49, 0x6E, 
  0x74, 0x36, 0x34, 0x29,       // 컬럼 유형: 'Nullable(UInt64)'
  
  // -- 널 허용 마스크 --
  0x00,                         // 행 0: NOT NULL
  0x01,                         // 행 1: NULL
  0x00,                         // 행 2: NOT NULL
  0x01,                         // 행 3: NULL
  0x00,                         // 행 4: NOT NULL
  
  // -- UInt64 값 --
  0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00,       // 행 0: UInt64 값 0

  // 블록 내에 해당 숫자의 실제 값이 존재하더라도,
  // 사용자에게는 NULL로 반환됩니다!
  0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00,       // 행 #1: NULL
  
  0x02, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00,       // 행 #2: UInt64 값 2
  
  0x03, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00,       // 행 #3: NULL (행 #1과 동일)
  
  0x04, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00,       // 행 #4: UInt64 값 4
]);
```

`Nullable(String)`도 비슷한 방식으로 작동합니다. null 표시자는 항상 널 허용 마스크 바이트에서 오며 —
마스크 값이 `0x01`이면 문자열 내용과 관계없이 해당 행은 `NULL`입니다. `NULL` 행의 경우,
내부 문자열은 빈 문자열(LEB128 길이 `0`)로 저장됩니다. 비-`NULL` 빈
문자열 역시 LEB128 길이가 `0`이므로, 두 경우를 구분하는 것은 마스크 바이트뿐입니다. 예를 들어, 다음 쿼리:

```bash theme={null}
curl -XPOST "http://localhost:8123?default_format=Native" \  --data-binary "SELECT if(number % 2 = 0, toString(number), NULL) :: Nullable(String) AS maybe_str                 FROM system.numbers LIMIT 5" \  > out.bin
```

출력은 다음과 같습니다:

```js theme={null}
const data = new Uint8Array([
  // --- 블록 헤더 ---
  0x01, // LEB128 - 컬럼 1개
  0x05, // LEB128 - 행 5개

  // -- 컬럼 헤더 --
  0x09, // LEB128 - 컬럼 이름 9바이트
  0x6d,
  0x61,
  0x79,
  0x62,
  0x65,
  0x5f,
  0x73,
  0x74,
  0x72, // 컬럼 이름: 'maybe_str'

  0x10, // LEB128 - 컬럼 유형 16바이트
  0x4e,
  0x75,
  0x6c,
  0x6c,
  0x61,
  0x62,
  0x6c,
  0x65,
  0x28,
  0x53,
  0x74,
  0x72,
  0x69,
  0x6e,
  0x67,
  0x29, // 컬럼 유형: 'Nullable(String)'

  // -- 널 허용 마스크 --
  0x00, // 행 0: NOT NULL
  0x01, // 행 1: NULL
  0x00, // 행 2: NOT NULL
  0x01, // 행 3: NULL
  0x00, // 행 4: NOT NULL

  // -- String 값 --
  0x01,
  0x30, // 행 0: LEB128 == 1, String '0'
  0x00, // 행 1: LEB128 == 0, NULL
  0x01,
  0x32, // 행 2: LEB128 == 1, String '2'
  0x00, // 행 3: LEB128 == 0, NULL
  0x01,
  0x34, // 행 4: LEB128 == 1, String '4'
])
```

<div id="lowcardinality">
  #### LowCardinality
</div>

`LowCardinality`가 투명하게 처리되는 [RowBinary](/ko/reference/formats/RowBinary/RowBinary#lowcardinality)와 달리, Native 형식은 딕셔너리 기반의 열 지향 인코딩을 사용합니다. 컬럼은 버전 접두사로 시작하고, 이어서 고유 값 딕셔너리와 해당 딕셔너리를 참조하는 정수 인덱스 배열로 인코딩됩니다.

<Note>
  컬럼은 `LowCardinality(Nullable(T))`로 정의할 수 있지만, `Nullable(LowCardinality(T))`로 정의할 수는 없습니다 — 이렇게 정의하면 항상 서버에서 오류가 발생합니다.
</Note>

버전 접두사는 값이 `1`인 `UInt64(LE)`이며, 컬럼마다 한 번만 기록됩니다. 그다음 각 블록마다 다음이 기록됩니다.

* `UInt64(LE)` — `IndexesSerializationType` 비트 필드입니다. 비트 0–7은 인덱스 너비를 인코딩합니다(0 = UInt8, 1 = UInt16, 2 = UInt32, 3 = UInt64). 비트 8(`NeedGlobalDictionaryBit`)은 Native 형식에서는 절대 설정되지 않습니다(이 값이 나타나면 서버가 예외를 발생시킵니다). 비트 9는 추가 딕셔너리 키가 있음을 나타냅니다. 비트 10은 딕셔너리를 재설정해야 함을 나타냅니다.
* `UInt64(LE)` — 딕셔너리 키 수이며, 뒤이어 내부 타입 인코딩을 사용해 키가 일괄 직렬화되어 기록됩니다.
* `UInt64(LE)` — 행 수이며, 뒤이어 적절한 UInt 너비를 사용해 인덱스 값이 일괄 직렬화되어 기록됩니다.

딕셔너리에는 항상 인덱스 0에 기본값이 포함됩니다(예: `String`의 경우 빈 문자열, 숫자 타입의 경우 0). `LowCardinality(Nullable(T))`에서는 인덱스 0이 `NULL`을 나타내며, 키는 `Nullable` 래퍼 없이 직렬화됩니다.

예를 들어, 5개 행 `['foo', 'bar', 'baz', 'foo', 'bar']`를 가지는 `LowCardinality(String)`은 다음과 같습니다:

```text theme={null}
// 버전 접두사
01 00 00 00 00 00 00 00    // UInt64(LE) = 1

// IndexesSerializationType: UInt8 인덱스, 키 있음, 딕셔너리 업데이트
00 06 00 00 00 00 00 00    // UInt64(LE) = 0x0600

04 00 00 00 00 00 00 00    // 딕셔너리 키 4개
00                          // key 0: "" (기본값)
03 66 6f 6f                 // key 1: "foo"
03 62 61 72                 // key 2: "bar"
03 62 61 7a                 // key 3: "baz"

05 00 00 00 00 00 00 00    // 5행
01 02 03 01 02              // 인덱스 → "foo", "bar", "baz", "foo", "bar"
```

`LowCardinality(Nullable(String))`에서는 인덱스 0은 `NULL`입니다:

```text theme={null}
01 00 00 00 00 00 00 00    // 버전
00 06 00 00 00 00 00 00    // IndexesSerializationType
03 00 00 00 00 00 00 00    // 키 3개
00                          // 키 0: NULL
00                          // 키 1: "" (기본값)
03 79 65 73                 // 키 2: "yes"
05 00 00 00 00 00 00 00    // 행 5개
02 00 02 00 02              // 인덱스 → "yes", NULL, "yes", NULL, "yes"
```

<div id="array">
  #### 배열
</div>

각 배열 앞에 LEB128 요소 개수가 붙는 [RowBinary](/ko/reference/formats/RowBinary/RowBinary#array)와 달리, Native 형식에서는 배열을 2개의 열 지향 하위 스트림으로 인코딩합니다:

* 누적 `UInt64` 오프셋 N개(리틀 엔디언, 각각 8바이트). `i`번째 행에는 `offset[i] - offset[i-1]`개의 요소가 있으며, `offset[-1]`은 암묵적으로 0입니다.
* 모든 행의 중첩 요소를 하나로 이어서 연속적으로 일괄 직렬화합니다.

예를 들어, 3개의 행 `[[0, 10], [1, 11], [2, 12]]`를 가진 `Array(UInt32)`는 다음과 같습니다:

```text theme={null}
// 오프셋
02 00 00 00 00 00 00 00    // 2 (행 0: 요소 2개)
04 00 00 00 00 00 00 00    // 4 (행 1: 요소 2개)
06 00 00 00 00 00 00 00    // 6 (행 2: 요소 2개)

// 중첩된 UInt32 값 (총 6개)
00 00 00 00                 // 0
0a 00 00 00                 // 10
01 00 00 00                 // 1
0b 00 00 00                 // 11
02 00 00 00                 // 2
0c 00 00 00                 // 12
```

빈 배열은 이전 행과 동일한 오프셋을 가집니다. 예를 들어, 4개 행의 `Array(String)` 값이 `[[], ['0'], ['0','1'], ['0','1','2']]`인 경우는 다음과 같습니다:

```text theme={null}
00 00 00 00 00 00 00 00    // 0 (빈 배열)
01 00 00 00 00 00 00 00    // 1
03 00 00 00 00 00 00 00    // 3
06 00 00 00 00 00 00 00    // 6
01 30                       // "0"
01 30                       // "0"
01 31                       // "1"
01 30                       // "0"
01 31                       // "1"
01 32                       // "2"
```

<div id="map">
  #### 맵
</div>

`Map(K, V)`는 `Array(Tuple(K, V))`로 인코딩됩니다. 즉, 배열 오프셋 다음에 모든 키가 나오고, 그 뒤에 모든 값이 나옵니다. 이는 각 항목마다 키와 값이 번갈아 저장되는 [RowBinary](/ko/reference/formats/RowBinary/RowBinary#map)와 다릅니다.

예시로, 3개의 행이 있는 `Map(String, UInt64)` `[{'a':0,'b':10}, {'a':1,'b':11}, {'a':2,'b':12}]`는 다음과 같습니다:

```text theme={null}
// 배열 오프셋
02 00 00 00 00 00 00 00    // 2
04 00 00 00 00 00 00 00    // 4
06 00 00 00 00 00 00 00    // 6

// 모든 키 (6개의 String)
01 61                       // "a"
01 62                       // "b"
01 61                       // "a"
01 62                       // "b"
01 61                       // "a"
01 62                       // "b"

// 모든 값 (6개의 UInt64)
00 00 00 00 00 00 00 00    // 0
0a 00 00 00 00 00 00 00    // 10
01 00 00 00 00 00 00 00    // 1
0b 00 00 00 00 00 00 00    // 11
02 00 00 00 00 00 00 00    // 2
0c 00 00 00 00 00 00 00    // 12
```

<div id="variant">
  #### Variant
</div>

각 행에 자체 판별자 바이트와 그 뒤의 값을 인라인으로 담는 [RowBinary](/ko/reference/formats/RowBinary/RowBinary#variant)와 달리, Native 형식은 판별자와 데이터를 분리합니다.

<Warning>
  RowBinary와 마찬가지로 정의에 있는 타입은 항상 알파벳순으로 정렬되며, 판별자는 그 정렬된 목록의 인덱스입니다. `0xFF` (255)는 `NULL`을 나타냅니다.
</Warning>

`Variant` 컬럼은 다음과 같이 인코딩됩니다.

* `UInt64(LE)` 판별자 모드 접두사 (`0` = BASIC, `1` = COMPACT). Native 형식 출력은 일반적으로 BASIC (`0`)을 사용하며, COMPACT 모드는 `use_compact_variant_discriminators_serialization`이 활성화된 상태로 저장된 데이터를 읽을 때 나타날 수 있습니다.
* 각 행마다 하나씩, N개의 `UInt8` 판별자.
* 각 variant type의 데이터는 판별자 순서대로, 해당하는 행만 포함하는 별도의 대량 컬럼으로 인코딩됩니다.

예를 들어, `Variant(String, UInt32)`에 5개의 행 `[0::UInt32, 'hello', NULL, 3::UInt32, 'hello']`가 있는 경우(정렬 결과: `String` = 0, `UInt32` = 1):

```text theme={null}
00 00 00 00 00 00 00 00    // 판별자 모드 = BASIC
01 00 ff 01 00              // UInt32, String, NULL, UInt32, String

// String (값 2개, 1번 및 4번 행)
05 68 65 6c 6c 6f          // "hello"
05 68 65 6c 6c 6f          // "hello"

// UInt32 (값 2개, 0번 및 3번 행)
00 00 00 00                 // 0
03 00 00 00                 // 3
```

<div id="dynamic">
  #### Dynamic
</div>

각 값이 자체적으로 타입 정보를 포함하는(타입 접두사 + 값) [RowBinary](/ko/reference/formats/RowBinary/RowBinary#dynamic)와 달리, Native 형식에서는 `Dynamic`을 구조체 접두사 다음에 [Variant](#variant) 컬럼이 이어지는 형태로 직렬화합니다.

구조체 접두사에는 `UInt64(LE)` 직렬화 버전, 동적 타입의 개수(VarUInt), 그리고 문자열 형태의 타입 이름이 포함됩니다. V1 버전에서는 호환성을 위해 타입 개수를 두 번 기록합니다. 그 뒤에 오는 데이터는 동적 타입과 내부 `SharedVariant` 타입을 합친 뒤 알파벳순으로 정렬한 타입 목록을 가지는 `Variant` 컬럼입니다.

예를 들어, 5개의 행 `[0::UInt32, 'hello', NULL, 3::UInt32, 'hello']`이 있는 `Dynamic`은 다음과 같습니다:

```text theme={null}
// 구조 접두사 (V1)
01 00 00 00 00 00 00 00    // 버전 = V1
02                          // 타입 수 (V1은 두 번 기록)
02                          // 타입 수
06 53 74 72 69 6e 67       // "String"
06 55 49 6e 74 33 32       // "UInt32"

// Variant 데이터: Variant(SharedVariant, String, UInt32)
// 판별자: SharedVariant=0, String=1, UInt32=2
00 00 00 00 00 00 00 00    // 판별자 모드 = BASIC
02 01 ff 02 01              // UInt32, String, NULL, UInt32, String
// SharedVariant: 값 0개
05 68 65 6c 6c 6f          // String: "hello"
05 68 65 6c 6c 6f          // String: "hello"
00 00 00 00                 // UInt32: 0
03 00 00 00                 // UInt32: 3
```

<div id="json">
  #### JSON
</div>

각 행에 경로 이름과 값이 함께 포함되어 자체적으로 기술되는 [RowBinary](/ko/reference/formats/RowBinary/RowBinary#json)와 달리, Native 형식은 `JSON`을 열 지향 구조로 직렬화합니다. 인코딩은 복잡하고 버전에 따라 달라집니다. 즉, 직렬화 버전, 동적 경로 이름, shared data 레이아웃을 포함하는 구조체 접두사로 구성되며, 그 뒤에 타입이 지정된 경로(각각 벌크 컬럼), 동적 경로(각각 [Dynamic](#dynamic) 컬럼), 그리고 오버플로우 경로용 shared data가 이어집니다.

더 간단한 상호 운용성을 위해 `output_format_native_write_json_as_string=1` 설정 사용을 고려하십시오. 이 설정은 JSON 컬럼을 일반 JSON 텍스트 문자열(각 행당 `String` 1개)로 직렬화합니다.)
