JSON을 파싱하기 위한 함수 집합은 두 가지입니다.
simpleJSON (visitParam) 함수
ClickHouse에는 단순화된 JSON을 처리하기 위한 특수 함수가 있습니다. 이러한 JSON 함수는 모두 JSON이 어떤 형태일 수 있는지에 대해 강한 전제를 둡니다. 작업을 최대한 빠르게 수행하기 위해 필요한 최소한의 처리만 하도록 설계되었습니다.
다음과 같은 가정을 전제로 합니다:
- 필드 이름(함수 인수)은 상수여야 합니다.
- 필드 이름은 JSON에서 일종의 정규화된 형식으로 인코딩되어 있어야 합니다. 예를 들어
simpleJSONHas('{"abc":"def"}', 'abc') = 1이지만, simpleJSONHas('{"\\u0061\\u0062\\u0063":"def"}', 'abc') = 0입니다.
- 필드는 중첩 수준과 관계없이 모든 레벨에서 구분 없이 검색됩니다. 일치하는 필드가 여러 개 있으면 첫 번째 항목이 사용됩니다.
- JSON에는 문자열 리터럴 밖에 공백 문자가 없습니다.
이 함수들은 simdjson을 기반으로 하며, 더 복잡한 JSON 파싱 요구 사항을 처리하도록 설계되었습니다.
이 함수들은 JSON 객체에서 값을 추출할 때 ASCII 기준으로 대소문자를 구분하지 않는 방식으로 키를 매칭합니다.
대소문자를 구분하는 대응 함수와 동일하게 동작하지만, 객체 키를 매칭할 때는 대소문자를 구분하지 않습니다.
대소문자만 다른 여러 키가 일치하면 첫 번째 일치 항목을 반환합니다.
이 함수들은 대소문자를 구분하는 대응 함수보다 성능이 떨어질 수 있으므로, 가능하면 일반 JSONExtract 함수를 사용하십시오.
도입 버전: v24.8.0
JSON 컬럼 각 행에 저장된 모든 경로 목록을 반환합니다.
구문
인수
반환 값
JSON 컬럼에 있는 모든 경로의 배열을 반환합니다. Array(String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONAllPaths(json) FROM test;
┌─json─────────────────────────────────┬─JSONAllPaths(json)─┐
│ {"a":"42"} │ ['a'] │
│ {"b":"Hello"} │ ['b'] │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ ['a','c'] │
└──────────────────────────────────────┴────────────────────┘
도입 버전: v24.8.0
JSON 컬럼 각 행에 저장된 모든 경로와 해당 데이터 타입의 목록을 반환합니다.
구문
JSONAllPathsWithTypes(json)
인수
반환 값
JSON 컬럼에 있는 모든 경로와 각 경로의 데이터 타입으로 이루어진 맵을 반환합니다. Map(String, String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONAllPathsWithTypes(json) FROM test;
┌─json─────────────────────────────────┬─JSONAllPathsWithTypes(json)───────────────┐
│ {"a":"42"} │ {'a':'Int64'} │
│ {"b":"Hello"} │ {'b':'String'} │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ {'a':'Array(Nullable(Int64))','c':'Date'} │
└──────────────────────────────────────┴───────────────────────────────────────────┘
도입 버전: v26.4.0
JSON 컬럼의 각 행에 있는 모든 값을 문자열 배열로 반환합니다.
값은 텍스트 형식으로 직렬화되며 경로 이름순으로 정렬됩니다.
구문
인수
반환 값
JSON 컬럼의 모든 값을 문자열 형태로 담은 배열을 반환합니다. Array(String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json": {"a": 42}}, {"json": {"b": "Hello"}}, {"json": {"a": [1, 2, 3], "c": "2020-01-01"}}
SELECT json, JSONAllValues(json) FROM test;
┌─json─────────────────────────────────┬─JSONAllValues(json)──────┐
│ {"a":42} │ ['42'] │
│ {"b":"Hello"} │ ['Hello'] │
│ {"a":[1,2,3],"c":"2020-01-01"} │ ['[1,2,3]','2020-01-01'] │
└──────────────────────────────────────┴──────────────────────────┘
도입 버전: v23.2.0
최상위 JSON 배열의 요소 수를 반환합니다.
입력 JSON 문자열이 유효하지 않으면 NULL을 반환합니다.
구문
별칭: JSON_ARRAY_LENGTH
인수
json — 유효한 JSON 문자열입니다. String
반환 값
json이 유효한 JSON 배열 문자열이면 배열의 요소 수를 반환하고, 그렇지 않으면 NULL을 반환합니다. Nullable(UInt64)
예시
사용 예시
SELECT
JSONArrayLength(''),
JSONArrayLength('[1,2,3]');
┌─JSONArrayLength('')─┬─JSONArrayLength('[1,2,3]')─┐
│ ᴺᵁᴸᴸ │ 3 │
└─────────────────────┴────────────────────────────┘
도입 버전: v24.8.0
JSON 컬럼에서 별도의 서브컬럼으로 저장된 동적 경로 목록을 반환합니다.
구문
인수
반환 값
JSON 컬럼에 있는 동적 경로의 배열을 반환합니다. Array(String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONDynamicPaths(json) FROM test;
┌─json─────────────────────────────────┬─JSONDynamicPaths(json)─┐
│ {"a":"42"} │ ['a'] │
│ {"b":"Hello"} │ [] │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ ['a'] │
└──────────────────────────────────────┴────────────────────────┘
JSONDynamicPathsWithTypes
도입 버전: v24.8.0
JSON 컬럼의 각 행에서 별도 서브컬럼으로 저장된 동적 경로 목록과 해당 타입을 반환합니다.
구문
JSONDynamicPathsWithTypes(json)
인수
반환 값
JSON 컬럼에서 동적 경로와 해당 데이터 타입의 맵을 반환합니다. Map(String, String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONDynamicPathsWithTypes(json) FROM test;
┌─json─────────────────────────────────┬─JSONDynamicPathsWithTypes(json)─┐
│ {"a":"42"} │ {'a':'Int64'} │
│ {"b":"Hello"} │ {} │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ {'a':'Array(Nullable(Int64))'} │
└──────────────────────────────────────┴─────────────────────────────────┘
도입 버전: v19.14.0
JSON을 파싱하여 지정한 ClickHouse 데이터 타입의 값을 추출합니다.
구문
JSONExtract(json[, indices_or_keys, ...], return_type)
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 0개 이상의 인수로 이루어진 목록이며, 각 인수는 문자열 또는 정수일 수 있습니다. String 또는 (U)Int*
return_type — 반환할 ClickHouse 데이터 타입입니다. String
반환 값
가능하면 지정된 ClickHouse 데이터 타입의 값을 반환하고, 그렇지 않으면 해당 타입의 기본값을 반환합니다.
예시
사용 예시
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'Tuple(String, Array(Float64))') AS res;
┌─res──────────────────────────────┐
│ ('hello',[-100,200,300]) │
└──────────────────────────────────┘
도입 버전: v20.1.0
JSON 배열의 각 요소를 파싱되지 않은 문자열로 표현한 배열을 반환합니다.
구문
JSONExtractArrayRaw(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각각 문자열 또는 정수일 수 있는 인수 0개 이상으로 이루어진 목록입니다. String 또는 (U)Int*
반환 값
JSON 배열의 요소로 이루어진 문자열 배열을 반환합니다. 해당 부분이 배열이 아니거나 존재하지 않으면 빈 배열을 반환합니다. Array(String)
예시
사용 예시
SELECT JSONExtractArrayRaw('{"a": "hello", "b": [-100, 200.0, "hello"]}', 'b') AS res;
┌─res──────────────────────────┐
│ ['-100','200.0','"hello"'] │
└──────────────────────────────┘
도입 버전: v25.8.0
대소문자를 구분하지 않는 키 매칭을 사용하여 JSON 배열의 각 요소를 파싱되지 않은 문자열 형태로 표현한 배열을 반환합니다. 이 함수는 JSONExtractArrayRaw와 유사합니다.
구문
JSONExtractArrayRawCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 배열을 탐색하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
원시 JSON 문자열 배열을 반환합니다. Array(String)
예시
기본
SELECT JSONExtractArrayRawCaseInsensitive('{"Items": [1, 2, 3]}', 'ITEMS')
도입 버전: v20.1.0
JSON을 파싱하여 Bool 유형의 값을 추출합니다.
구문
JSONExtractBool(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각 항목이 문자열 또는 정수일 수 있는 인수 목록이며, 0개 이상 지정할 수 있습니다. String 또는 (U)Int*
반환 값
값이 존재하면 Bool 값을 반환하며, 그렇지 않으면 0을 반환합니다. Bool
예시
사용 예시
SELECT JSONExtractBool('{"passed": true}', 'passed') AS res;
도입 버전: v25.8.0
JSON을 파싱하여 키 매칭을 사용해 불리언 값을 추출합니다. 이 함수는 JSONExtractBool와 유사합니다.
구문
JSONExtractBoolCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드로 이동하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다. String 또는 (U)Int*
반환 값
추출된 불리언 값(true는 1, false는 0)을 반환합니다. 값을 찾지 못하면 0을 반환합니다. UInt8
예시
기본
SELECT JSONExtractBoolCaseInsensitive('{"IsActive": true}', 'isactive')
지원 버전: v25.8.0
JSON을 파싱하고 대소문자를 구분하지 않는 키 매칭으로 지정된 ClickHouse 데이터 타입의 값을 추출합니다. 이 함수는 JSONExtract와 유사합니다.
구문
JSONExtractCaseInsensitive(json [, indices_or_keys...], return_type)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드로 이동하는 데 사용할 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
return_type — 추출할 ClickHouse 데이터 타입 String
반환 값
지정된 데이터 타입으로 추출된 값을 반환합니다. Any
예시
int_type
SELECT JSONExtractCaseInsensitive('{"Number": 123}', 'number', 'Int32')
array_type
SELECT JSONExtractCaseInsensitive('{"List": [1, 2, 3]}', 'list', 'Array(Int32)')
도입 버전: v20.1.0
JSON을 파싱하여 Float 유형의 값을 추출합니다.
구문
JSONExtractFloat(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 0개 이상의 인수로 이루어진 목록이며, 각 인수는 문자열 또는 정수일 수 있습니다. String 또는 (U)Int*
반환 값
값이 존재하면 Float 값을 반환하고, 그렇지 않으면 0을 반환합니다. Float64
예시
사용 예시
SELECT JSONExtractFloat('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 2) AS res;
도입 버전: v25.8.0
JSON을 파싱하고 키 매칭을 사용해 Float 유형의 값을 추출합니다. 이 함수는 JSONExtractFloat와 유사합니다.
구문
JSONExtractFloatCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드로 이동하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다. String 또는 (U)Int*
반환 값
추출된 Float 값을 반환합니다. 값을 찾을 수 없거나 변환할 수 없는 경우 0을 반환합니다. Float64
예시
기본
SELECT JSONExtractFloatCaseInsensitive('{"Price": 12.34}', 'PRICE')
도입된 버전: v20.1.0
JSON을 파싱하여 Int 유형의 값을 추출합니다.
구문
JSONExtractInt(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각 항목이 문자열 또는 정수일 수 있는 0개 이상의 인수 목록입니다. String 또는 (U)Int*
반환 값
값이 있으면 Int 값을 반환하고, 없으면 0을 반환합니다. Int64
예시
사용 예시
SELECT JSONExtractInt('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 1) AS res;
┌──res─┐
│ -100 │
└──────┘
도입 버전: v25.8.0
JSON을 파싱하고 대소문자를 구분하지 않는 키 매칭으로 Int 유형의 값을 추출합니다. 이 함수는 JSONExtractInt와 유사합니다.
구문
JSONExtractIntCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드에 접근하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
추출된 Int 값을 반환합니다. 값을 찾을 수 없거나 변환할 수 없으면 0을 반환합니다. Int64
예시
기본
SELECT JSONExtractIntCaseInsensitive('{"Value": 123}', 'value')
중첩
SELECT JSONExtractIntCaseInsensitive('{"DATA": {"COUNT": 42}}', 'data', 'Count')
도입 버전: v21.11.0
JSON 문자열을 파싱하여 키를 추출합니다.
구문
JSONExtractKeys(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 0개 이상의 인수로 이루어진 목록이며, 각 인수는 문자열 또는 정수일 수 있습니다. String 또는 (U)Int*
반환 값
JSON 객체의 키로 이루어진 배열을 반환합니다. Array(String)
예시
사용 예시
SELECT JSONExtractKeys('{"a": "hello", "b": [-100, 200.0, 300]}') AS res;
┌─res─────────┐
│ ['a','b'] │
└─────────────┘
도입 버전: v20.1.0
값이 지정된 ClickHouse 데이터 타입인 JSON에서 key-value 쌍을 파싱합니다.
구문
JSONExtractKeysAndValues(json[, indices_or_keys, ...], value_type)
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각 인수는 문자열 또는 정수일 수 있으며, 이러한 인수를 0개 이상 나열한 목록입니다. String 또는 (U)Int*
value_type — 값의 ClickHouse 데이터 타입입니다. String
반환 값
파싱된 key-value 쌍으로 구성된 튜플 배열을 반환합니다. Array(Tuple(String, value_type))
예시
사용 예시
SELECT JSONExtractKeysAndValues('{"x": {"a": 5, "b": 7, "c": 11}}', 'Int8', 'x') AS res;
┌─res────────────────────┐
│ [('a',5),('b',7),('c',11)] │
└────────────────────────┘
JSONExtractKeysAndValuesCaseInsensitive
도입 버전: v25.8.0
대소문자를 구분하지 않는 키 매칭을 사용해 JSON에서 key-value 쌍을 파싱합니다. 이 함수는 JSONExtractKeysAndValues와 유사합니다.
구문
JSONExtractKeysAndValuesCaseInsensitive(json [, indices_or_keys...], value_type)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 객체까지 탐색하는 데 사용할 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
value_type — 값의 ClickHouse 데이터 타입입니다 String
반환 값
key-value 쌍을 포함하는 튜플의 배열을 반환합니다. Array(Tuple(String, T))
예시
기본
SELECT JSONExtractKeysAndValuesCaseInsensitive('{"Name": "Alice", "AGE": 30}', 'String')
[('Name','Alice'),('AGE','30')]
JSONExtractKeysAndValuesRaw
도입 버전: v20.4.0
JSON 객체의 키와 값을 담은 튜플 배열을 반환합니다. 모든 값은 파싱되지 않은 문자열로 표현됩니다.
구문
JSONExtractKeysAndValuesRaw(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각 항목이 문자열 또는 정수일 수 있는 0개 이상의 인수 목록입니다. String 또는 (U)Int*
반환 값
값이 파싱되지 않은 문자열인, 파싱된 key-value 쌍으로 이루어진 튜플 배열을 반환합니다. Array(Tuple(String, String))
예시
사용 예시
SELECT JSONExtractKeysAndValuesRaw('{"a": [-100, 200.0], "b": "hello"}') AS res;
┌─res──────────────────────────────────┐
│ [('a','[-100,200.0]'),('b','"hello"')] │
└──────────────────────────────────────┘
JSONExtractKeysAndValuesRawCaseInsensitive
도입 버전: v25.8.0
대소문자를 구분하지 않는 키 매칭을 사용해 JSON에서 원시 key-value 쌍을 추출합니다. 이 함수는 JSONExtractKeysAndValuesRaw와 유사합니다.
구문
JSONExtractKeysAndValuesRawCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 객체 내부를 탐색하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
원시 문자열 형태의 key-value 쌍을 포함하는 튜플 배열을 반환합니다. Array(Tuple(String, String))
예시
기본
SELECT JSONExtractKeysAndValuesRawCaseInsensitive('{"Name": "Alice", "AGE": 30}')
[('Name','"Alice"'),('AGE','30')]
지원 버전: v25.8.0
JSON 문자열을 파싱하고, 대소문자를 구분하지 않는 키 매칭으로 중첩된 객체를 탐색하여 키를 추출합니다. 이 함수는 JSONExtractKeys와 유사합니다.
구문
JSONExtractKeysCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 객체로 탐색하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
JSON 객체의 키 배열을 반환합니다. Array(String)
예시
기본
SELECT JSONExtractKeysCaseInsensitive('{"Name": "Alice", "AGE": 30}')
중첩
SELECT JSONExtractKeysCaseInsensitive('{"User": {"name": "John", "AGE": 25}}', 'user')
도입된 버전: v20.1.0
JSON의 일부를 파싱되지 않은 문자열로 반환합니다.
구문
JSONExtractRaw(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 0개 이상의 인수로 이루어진 목록이며, 각 인수는 문자열 또는 정수일 수 있습니다. String 또는 (U)Int*
반환 값
JSON의 해당 부분을 파싱되지 않은 문자열로 반환합니다. 해당 부분이 없거나 타입이 올바르지 않으면 빈 문자열을 반환합니다. String
예시
사용 예시
SELECT JSONExtractRaw('{"a": "hello", "b": [-100, 200.0, 300]}', 'b') AS res;
┌─res──────────────┐
│ [-100,200.0,300] │
└──────────────────┘
도입 버전: v25.8.0
대소문자를 구분하지 않는 키 매칭을 사용해 JSON의 일부를 파싱하지 않은 문자열로 반환합니다. 이 함수는 JSONExtractRaw와 유사합니다.
구문
JSONExtractRawCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드에 접근하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치 여부를 판단합니다 String 또는 (U)Int*
반환 값
추출된 요소의 원본 JSON 문자열을 반환합니다. String
예시
객체
SELECT JSONExtractRawCaseInsensitive('{"Object": {"key": "value"}}', 'OBJECT')
지원 시작 버전: v20.1.0
JSON을 파싱하여 String 유형의 값을 추출합니다.
구문
JSONExtractString(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 각 항목이 문자열 또는 정수일 수 있는, 0개 이상의 인수 목록입니다. String 또는 (U)Int*
반환 값
값이 있으면 String 값을 반환하고, 없으면 빈 문자열을 반환합니다. String
예시
사용 예시
SELECT JSONExtractString('{"a": "hello", "b": [-100, 200.0, 300]}', 'a') AS res;
┌─res───┐
│ hello │
└───────┘
도입 버전: v25.8.0
JSON을 파싱해 대소문자를 구분하지 않는 키 매칭으로 문자열을 추출합니다. 이 함수는 JSONExtractString과 유사합니다.
구문
JSONExtractStringCaseInsensitive(json [, indices_or_keys]...)
인수
json — 파싱할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드까지 이동하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
추출된 문자열 값을 반환합니다. 찾지 못하면 빈 문자열을 반환합니다. String
예시
기본
SELECT JSONExtractStringCaseInsensitive('{"ABC": "def"}', 'abc')
중첩
SELECT JSONExtractStringCaseInsensitive('{"User": {"Name": "John"}}', 'user', 'name')
도입 버전: v20.1.0
JSON을 파싱하여 UInt 유형의 값을 추출합니다.
구문
JSONExtractUInt(json [, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 0개 이상의 인수로 이루어진 목록이며, 각 인수는 문자열 또는 정수일 수 있습니다. String 또는 (U)Int*
반환 값
값이 존재하면 UInt 값을 반환하며, 그렇지 않으면 0을 반환합니다. UInt64
예시
사용 예시
SELECT JSONExtractUInt('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', -1) AS res;
도입 버전: v25.8.0
JSON을 파싱하고 대소문자를 구분하지 않는 키 매칭을 사용하여 UInt 유형의 값을 추출합니다. 이 함수는 JSONExtractUInt와 유사합니다.
구문
JSONExtractUIntCaseInsensitive(json [, indices_or_keys]...)
인수
json — parse할 JSON 문자열 String
indices_or_keys — 선택 사항입니다. 필드에 도달하기 위한 인덱스 또는 키입니다. 키는 대소문자를 구분하지 않고 일치합니다 String 또는 (U)Int*
반환 값
추출된 UInt 값을 반환합니다. 찾을 수 없거나 변환할 수 없으면 0을 반환합니다. UInt64
예시
기본
SELECT JSONExtractUIntCaseInsensitive('{"COUNT": 789}', 'count')
도입 버전: v20.1.0
JSON 문서에 지정된 값이 존재하는지 확인합니다.
구문
JSONHas(json[ ,indices_or_keys, ...])
인수
반환 값
값이 json에 존재하면 1을, 그렇지 않으면 0을 반환합니다 UInt8
예시
사용 예시
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 'b') = 1;
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 4) = 0;
도입 버전: v20.1.0
인덱스(1부터 시작)에 해당하는 JSON 객체 필드의 키를 반환합니다. JSON이 문자열로 전달되면 먼저 파싱합니다. 두 번째 인수는 중첩된 객체 내부로 이동하기 위한 JSON 경로입니다. 이 함수는 지정된 위치의 키 이름을 반환합니다.
구문
JSONKey(json[, indices_or_keys, ...])
인수
json — 파싱할 JSON 문자열입니다. String
indices_or_keys — 중첩된 요소에 대한 경로를 지정하는 선택적 인덱스 또는 키 목록입니다. 각 인수는 문자열(키로 액세스) 또는 정수(1부터 시작하는 인덱스로 액세스)일 수 있습니다. String 또는 Int*
반환 값
JSON 객체에서 지정한 위치의 키 이름을 반환합니다. String
예시
사용 예시
SELECT JSONKey('{"a": "hello", "b": [-100, 200.0, 300]}', 1);
도입 버전: v20.1.0
JSON 배열 또는 JSON 객체의 길이를 반환합니다.
값이 없거나 유형이 올바르지 않으면 0을 반환합니다.
구문
JSONLength(json [, indices_or_keys, ...])
인수
반환 값
JSON 배열 또는 JSON 객체의 길이를 반환합니다. 값이 존재하지 않거나 타입이 올바르지 않으면 0을 반환합니다. UInt64
예시
사용 예시
SELECT JSONLength('{"a": "hello", "b": [-100, 200.0, 300]}', 'b') = 3;
SELECT JSONLength('{"a": "hello", "b": [-100, 200.0, 300]}') = 2;
도입 버전: v23.10.0
여러 JSON 객체를 병합해 생성된 JSON 객체 문자열을 반환합니다.
구문
JSONMergePatch(json1[, json2, ...])
별칭: jsonMergePatch
인수
json1[, json2, ...] — 유효한 JSON이 담긴 하나 이상의 문자열입니다. String
반환 값
JSON 객체 문자열이 유효한 경우, 머지된 JSON 객체 문자열을 반환합니다. String
예시
사용 예시
SELECT JSONMergePatch('{"a":1}', '{"name": "joey"}', '{"name": "tom"}', '{"name": "zoey"}') AS res;
┌─res───────────────────┐
│ {"a":1,"name":"zoey"} │
└───────────────────────┘
도입 버전: v24.8.0
JSON 컬럼의 공유 데이터 구조에 저장된 경로 목록을 반환합니다.
구문
JSONSharedDataPaths(json)
인수
반환 값
JSON 컬럼의 공유 데이터 구조에 저장된 경로 배열을 반환합니다. Array(String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONSharedDataPaths(json) FROM test;
┌─json─────────────────────────────────┬─JSONSharedDataPaths(json)─┐
│ {"a":"42"} │ [] │
│ {"b":"Hello"} │ ['b'] │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ ['c'] │
└──────────────────────────────────────┴───────────────────────────┘
JSONSharedDataPathsWithTypes
도입 버전: v24.8.0
JSON 컬럼의 각 행에 대해 공유 데이터 구조에 저장된 경로 목록과 해당 타입을 반환합니다.
구문
JSONSharedDataPathsWithTypes(json)
인수
반환 값
공유 데이터 구조에 저장된 경로와 해당 경로의 JSON 컬럼 내 데이터 타입을 담은 맵을 반환합니다. Map(String, String)
예시
사용 예시
CREATE TABLE test (json JSON(max_dynamic_paths=1)) ENGINE = Memory;
INSERT INTO test FORMAT JSONEachRow {"json" : {"a" : 42}}, {"json" : {"b" : "Hello"}}, {"json" : {"a" : [1, 2, 3], "c" : "2020-01-01"}}
SELECT json, JSONSharedDataPathsWithTypes(json) FROM test;
┌─json─────────────────────────────────┬─JSONSharedDataPathsWithTypes(json)─┐
│ {"a":"42"} │ {} │
│ {"b":"Hello"} │ {'b':'String'} │
│ {"a":["1","2","3"],"c":"2020-01-01"} │ {'c':'Date'} │
└──────────────────────────────────────┴─────────────────────────────────────┘
지원 시작 버전: v20.1.0
JSON 값의 유형을 반환합니다. 값이 존재하지 않으면 Null=0을 반환합니다.
구문
JSONType(json[, indices_or_keys, ...])
인수
반환 값
JSON 값의 타입을 문자열로 반환하며, 값이 없으면 Null=0을 반환합니다 Enum
예시
사용 예시
SELECT JSONType('{"a": "hello", "b": [-100, 200.0, 300]}') = 'Object';
SELECT JSONType('{"a": "hello", "b": [-100, 200.0, 300]}', 'a') = 'String';
SELECT JSONType('{"a": "hello", "b": [-100, 200.0, 300]}', 'b') = 'Array';
도입 버전: v21.8.0
값이 JSON 문서에 존재하면 1이 반환됩니다.
값이 존재하지 않으면 0이 반환됩니다.
구문
인수
json — 유효한 JSON 문자열입니다. String
path — 경로를 나타내는 문자열입니다. String
반환 값
값이 JSON 문서에 있으면 1을, 없으면 0을 반환합니다. UInt8
예시
사용 예시
SELECT JSON_EXISTS('{"hello":1}', '$.hello');
SELECT JSON_EXISTS('{"hello":{"world":1}}', '$.hello.world');
SELECT JSON_EXISTS('{"hello":["world"]}', '$.hello[*]');
SELECT JSON_EXISTS('{"hello":["world"]}', '$.hello[0]');
┌─JSON_EXISTS(⋯ '$.hello')─┐
│ 1 │
└──────────────────────────┘
┌─JSON_EXISTS(⋯llo.world')─┐
│ 1 │
└──────────────────────────┘
┌─JSON_EXISTS(⋯.hello[*]')─┐
│ 1 │
└──────────────────────────┘
┌─JSON_EXISTS(⋯.hello[0]')─┐
│ 1 │
└──────────────────────────┘
도입 버전: v21.8.0
JSON을 파싱하여 값을 JSON 배열 또는 JSON 객체로 추출합니다.
값이 존재하지 않으면 빈 문자열이 반환됩니다.
구문
인수
json — 유효한 JSON이 담긴 문자열입니다. String
path — 경로를 나타내는 문자열입니다. String
반환 값
추출된 JSON 배열 또는 JSON 객체를 문자열로 반환하며, 값이 없으면 빈 문자열을 반환합니다. String
예시
사용 예시
SELECT JSON_QUERY('{"hello":"world"}', '$.hello');
SELECT JSON_QUERY('{"array":[[0, 1, 2, 3, 4, 5], [0, -1, -2, -3, -4, -5]]}', '$.array[*][0 to 2, 4]');
SELECT JSON_QUERY('{"hello":2}', '$.hello');
SELECT toTypeName(JSON_QUERY('{"hello":2}', '$.hello'));
["world"]
[0, 1, 4, 0, -1, -4]
[2]
String
도입 버전: v21.11.0
JSON을 파싱하여 값을 JSON 스칼라로 추출합니다. 값이 존재하지 않으면 기본적으로 빈 문자열이 반환됩니다.
이 함수의 동작은 다음 설정으로 제어됩니다:
- SET
function_json_value_return_type_allow_nullable = true로 설정하면 NULL이 반환됩니다. 값이 복합 유형(예: struct, 배열, 맵)인 경우에는 기본적으로 빈 문자열이 반환됩니다.
- SET
function_json_value_return_type_allow_complex = true로 설정하면 복합 값이 반환됩니다.
구문
인수
json — 유효한 JSON이 담긴 문자열입니다. String
path — 경로를 나타내는 문자열입니다. String
반환 값
추출된 JSON 스칼라를 문자열로 반환합니다. 값이 없으면 빈 문자열을 반환합니다. String
예시
사용 예시
SELECT JSON_VALUE('{"hello":"world"}', '$.hello');
SELECT JSON_VALUE('{"array":[[0, 1, 2, 3, 4, 5], [0, -1, -2, -3, -4, -5]]}', '$.array[*][0 to 2, 4]');
SELECT JSON_VALUE('{"hello":2}', '$.hello');
SELECT JSON_VALUE('{"hello":"world"}', '$.b') settings function_json_value_return_type_allow_nullable=true;
도입 버전: v24.1.0
Dynamic 컬럼에서 지정된 타입의 컬럼을 추출합니다.
이 함수는 Dynamic 컬럼에서 특정 타입의 값을 추출할 수 있습니다. 행에 요청한 타입의 값이 있으면
해당 값을 반환합니다. 행에 다른 타입의 값이나 NULL이 있으면 스칼라 타입에는 NULL을 반환하고
배열 타입에는 빈 배열을 반환합니다.
구문
dynamicElement(dynamic, type_name)
인수
dynamic — 값을 추출할 Dynamic 컬럼입니다. Dynamic
type_name — 추출할 variant 타입의 이름입니다(예: ‘String’, ‘Int64’, ‘Array(Int64)’).
반환 값
Dynamic 컬럼에서 지정한 타입의 값을 반환합니다. 타입이 일치하지 않으면 NULL을 반환합니다(배열 타입인 경우 빈 배열을 반환). Any
예시
Dynamic 컬럼에서 다양한 타입 추출하기
CREATE TABLE test (d Dynamic) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT d, dynamicType(d), dynamicElement(d, 'String'), dynamicElement(d, 'Int64'), dynamicElement(d, 'Array(Int64)'), dynamicElement(d, 'Date'), dynamicElement(d, 'Array(String)') FROM test
┌─d─────────────┬─dynamicType(d)─┬─dynamicElement(d, 'String')─┬─dynamicElement(d, 'Int64')─┬─dynamicElement(d, 'Array(Int64)')─┬─dynamicElement(d, 'Date')─┬─dynamicElement(d, 'Array(String)')─┐
│ ᴺᵁᴸᴸ │ None │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ [] │ ᴺᵁᴸᴸ │ [] │
│ 42 │ Int64 │ ᴺᵁᴸᴸ │ 42 │ [] │ ᴺᵁᴸᴸ │ [] │
│ Hello, World! │ String │ Hello, World! │ ᴺᵁᴸᴸ │ [] │ ᴺᵁᴸᴸ │ [] │
│ [1,2,3] │ Array(Int64) │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ [1,2,3] │ ᴺᵁᴸᴸ │ [] │
└───────────────┴────────────────┴─────────────────────────────┴────────────────────────────┴───────────────────────────────────┴───────────────────────────┴────────────────────────────────────┘
v24.1.0에서 도입됨
Dynamic 컬럼의 각 행에 대한 variant 타입 이름을 반환합니다.
NULL을 포함하는 행의 경우 함수는 ‘None’을 반환합니다. 그 외의 모든 행에 대해서는 Dynamic 컬럼의 해당 행에 저장된 실제 데이터 타입을 반환합니다(예: ‘Int64’, ‘String’, ‘Array(Int64)’).
구문
인수
dynamic — 검사할 Dynamic 컬럼입니다. Dynamic
반환 값
각 행에 저장된 값의 타입 이름을 반환하며, NULL 값인 경우 ‘None’을 반환합니다. String
예시
Dynamic 컬럼의 타입 검사
CREATE TABLE test (d Dynamic) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT d, dynamicType(d) FROM test;
┌─d─────────────┬─dynamicType(d)─┐
│ ᴺᵁᴸᴸ │ None │
│ 42 │ Int64 │
│ Hello, World! │ String │
│ [1,2,3] │ Array(Int64) │
└───────────────┴────────────────┘
isDynamicElementInSharedData
도입 버전: v24.1.0
개별 서브컬럼으로 분리되어 저장되지 않고 공유 variant 포맷으로 저장된 Dynamic 컬럼의 행에 대해 true를 반환합니다.
Dynamic 컬럼에 max_types 제한이 있으면, 이 제한을 초과하는 값은 개별 타입의 서브컬럼으로 분리되지 않고
공유 바이너리 형식으로 저장됩니다. 이 함수는 어떤 행이 이 공유 형식으로 저장되었는지 식별합니다.
구문
isDynamicElementInSharedData(dynamic)
인수
반환 값
값이 공유 Variant 포맷으로 저장된 경우 true를, 개별 서브컬럼으로 저장되었거나 NULL인 경우 false를 반환합니다. Bool
예시
max_types 제한이 설정된 Dynamic 컬럼의 저장 포맷 확인
CREATE TABLE test (d Dynamic(max_types=2)) ENGINE = Memory;
INSERT INTO test VALUES (NULL), (42), ('Hello, World!'), ([1, 2, 3]);
SELECT d, isDynamicElementInSharedData(d) FROM test;
┌─d─────────────┬─isDynamicElementInSharedData(d)─┐
│ ᴺᵁᴸᴸ │ false │
│ 42 │ false │
│ Hello, World! │ true │
│ [1,2,3] │ true │
└───────────────┴─────────────────────────────────┘
도입 버전: v20.1.0
전달된 문자열이 유효한 JSON 형식인지 확인합니다.
구문
인수
json — 유효성을 검사할 JSON 문자열 String
반환 값
문자열이 유효한 JSON이면 1을, 그렇지 않으면 0을 반환합니다. UInt8
예시
사용 예시
SELECT isValidJSON('{"a": "hello", "b": [-100, 200.0, 300]}') = 1;
SELECT isValidJSON('not JSON') = 0;
정수를 사용해 JSON 배열과 JSON 객체 모두에 접근하기
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 0);
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 1);
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 2);
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', -1);
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', -2);
SELECT JSONHas('{"a": "hello", "b": [-100, 200.0, 300]}', 3);
도입 버전: v21.4.0
field_name이라는 이름의 필드 값에서 true/false 값을 파싱합니다.
결과는 UInt8입니다.
구문
simpleJSONExtractBool(json, field_name)
별칭: visitParamExtractBool
인수
반환 값
필드의 값이 true이면 1을 반환하고, 그렇지 않으면 0을 반환합니다. 즉, 다음과 같은 경우를 포함해(이에 국한되지 않음) 이 함수는 0을 반환합니다.
- 필드가 존재하지 않는 경우
- 필드에
true가 문자열로 포함된 경우. 예: {"field":"true"}.
- 필드에 숫자 값
1이 포함된 경우. UInt8
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":false,"bar":true}');
INSERT INTO jsons VALUES ('{"foo":"true","qux":1}');
SELECT simpleJSONExtractBool(json, 'bar') FROM jsons ORDER BY json;
SELECT simpleJSONExtractBool(json, 'foo') FROM jsons ORDER BY json;
도입 버전: v21.4.0
field_name이라는 이름의 필드 값에서 Float64를 파싱합니다.
field_name이 String 필드이면 문자열의 시작 부분에서 숫자를 파싱합니다.
필드가 존재하지 않거나 존재하더라도 숫자를 포함하지 않으면 0을 반환합니다.
구문
simpleJSONExtractFloat(json, field_name)
별칭: visitParamExtractFloat
인수
반환 값
필드가 존재하고 숫자를 포함하는 경우 해당 숫자를 반환하며, 그렇지 않으면 0을 반환합니다. Float64
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"-4e3"}');
INSERT INTO jsons VALUES ('{"foo":-3.4}');
INSERT INTO jsons VALUES ('{"foo":5}');
INSERT INTO jsons VALUES ('{"foo":"not1number"}');
INSERT INTO jsons VALUES ('{"baz":2}');
SELECT simpleJSONExtractFloat(json, 'foo') FROM jsons ORDER BY json;
도입 버전: v21.4.0
field_name이라는 이름의 field 값에서 Int64를 파싱합니다.
field_name이 문자열 field이면 문자열의 시작 부분에서 숫자를 파싱합니다.
field가 없거나, 있더라도 숫자를 포함하지 않으면 0을 반환합니다.
구문
simpleJSONExtractInt(json, field_name)
별칭: visitParamExtractInt
인수
반환 값
필드가 존재하고 숫자를 포함하고 있으면 해당 필드에서 파싱한 숫자를 반환하며, 그렇지 않으면 0을 반환합니다. Int64
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"-4e3"}');
INSERT INTO jsons VALUES ('{"foo":-3.4}');
INSERT INTO jsons VALUES ('{"foo":5}');
INSERT INTO jsons VALUES ('{"foo":"not1number"}');
INSERT INTO jsons VALUES ('{"baz":2}');
SELECT simpleJSONExtractInt(json, 'foo') FROM jsons ORDER BY json;
도입 버전: v21.4.0
field_name이라는 이름의 필드 값을 구분자를 포함한 String으로 반환합니다.
구문
simpleJSONExtractRaw(json, field_name)
별칭: visitParamExtractRaw
인수
반환 값
필드가 존재하면 구분자를 포함한 해당 필드의 값을 문자열로 반환하고, 그렇지 않으면 빈 문자열을 반환합니다. String
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"-4e3"}');
INSERT INTO jsons VALUES ('{"foo":-3.4}');
INSERT INTO jsons VALUES ('{"foo":5}');
INSERT INTO jsons VALUES ('{"foo":{"def":[1,2,3]}}');
INSERT INTO jsons VALUES ('{"baz":2}');
SELECT simpleJSONExtractRaw(json, 'foo') FROM jsons ORDER BY json;
"-4e3"
-3.4
5
{"def":[1,2,3]}
도입 버전: v21.4.0
field_name이라는 이름의 필드 값에서 큰따옴표로 둘러싸인 String을 파싱합니다.
구현 세부 사항
현재 기본 다국어 평면에 속하지 않는 \uXXXX\uYYYY 포맷의 코드 포인트는 지원하지 않습니다(UTF-8이 아니라 CESU-8로 변환됨).
구문
simpleJSONExtractString(json, field_name)
별칭: visitParamExtractString
인수
반환 값
구분자를 포함한 필드의 이스케이프 해제된 값을 문자열로 반환합니다. 필드에 큰따옴표로 둘러싸인 문자열이 없거나, 이스케이프 해제에 실패했거나, 필드가 존재하지 않으면 빈 문자열을 반환합니다. String
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"\\n\\u0000"}');
INSERT INTO jsons VALUES ('{"foo":"\\u263"}');
INSERT INTO jsons VALUES ('{"foo":"\\u263a"}');
INSERT INTO jsons VALUES ('{"foo":"hello}');
SELECT simpleJSONExtractString(json, 'foo') FROM jsons ORDER BY json;
도입 버전: v21.4.0
field_name이라는 이름의 필드 값에서 UInt64를 파싱합니다.
field_name이 문자열 필드이면 문자열의 시작 부분에서 숫자를 파싱합니다.
필드가 없거나 필드는 존재하지만 숫자를 포함하지 않으면 0을 반환합니다.
구문
simpleJSONExtractUInt(json, field_name)
별칭: visitParamExtractUInt
인수
반환 값
필드가 존재하고 숫자를 포함하면 해당 필드에서 파싱한 숫자를 반환하고, 그렇지 않으면 0을 반환합니다. UInt64
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"4e3"}');
INSERT INTO jsons VALUES ('{"foo":3.4}');
INSERT INTO jsons VALUES ('{"foo":5}');
INSERT INTO jsons VALUES ('{"foo":"not1number"}');
INSERT INTO jsons VALUES ('{"baz":2}');
SELECT simpleJSONExtractUInt(json, 'foo') FROM jsons ORDER BY json;
도입 버전: v21.4.0
field_name이라는 이름의 필드가 존재하는지 확인합니다.
구문
simpleJSONHas(json, field_name)
별칭: visitParamHas
인수
반환 값
필드가 존재하면 1을 반환하고, 그렇지 않으면 0을 반환합니다. UInt8
예시
사용 예시
CREATE TABLE jsons
(
`json` String
)
ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO jsons VALUES ('{"foo":"true","qux":1}');
SELECT simpleJSONHas(json, 'foo') FROM jsons;
SELECT simpleJSONHas(json, 'bar') FROM jsons;
도입 버전: v21.7.0
값을 JSON 표현으로 직렬화합니다. 다양한 데이터 타입과 중첩된 구조를 지원합니다.
64비트 정수 또는 그보다 큰 값(UInt64, Int128 등)은 기본적으로 따옴표로 묶입니다. 이 동작은 output_format_json_quote_64bit_integers 설정으로 제어합니다.
특수 값 NaN 및 inf는 null로 대체됩니다. 이를 표시하려면 output_format_json_quote_denormals 설정을 활성화하십시오.
Enum 값을 직렬화하면 함수는 해당 이름을 출력합니다.
관련 항목:
구문
인수
value — 직렬화할 값입니다. 값은 모든 데이터 타입이 될 수 있습니다. Any
반환 값
값의 JSON 표현을 반환합니다. String
예시
맵 직렬화
SELECT toJSONString(map('key1', 1, 'key2', 2));
┌─toJSONString(map('key1', 1, 'key2', 2))─┐
│ {"key1":1,"key2":2} │
└─────────────────────────────────────────┘
특수 값
SELECT toJSONString(tuple(1.25, NULL, NaN, +inf, -inf, [])) SETTINGS output_format_json_quote_denormals = 1;
┌─toJSONString(tuple(1.25, NULL, NaN, plus(inf), minus(inf), []))─┐
│ [1.25,null,"nan","inf","-inf",[]] │
└─────────────────────────────────────────────────────────────────┘