Skip to main content

설명

pg_clickhouse는 [외부 데이터 래퍼]를 포함해 ClickHouse 데이터베이스에서 원격 쿼리 실행을 지원하는 PostgreSQL 확장 기능입니다. PostgreSQL 14 이상과 ClickHouse 23.3 이상을 지원합니다.

시작하기

pg_clickhouse를 가장 간단하게 사용해 보려면 Docker image를 이용하는 방법이 있습니다. 이 이미지에는 pg_clickhouse와 [re2][re2 확장 기능]이 포함된 표준 PostgreSQL Docker image가 들어 있습니다:
ClickHouse 테이블 가져오기와 쿼리 푸시다운을 시작하려면 튜토리얼을 참조하십시오.

사용

버전 정책

pg_clickhouse는 공개 릴리스에 Semantic Versioning을 적용합니다.
  • API가 변경되면 메이저 버전이 증가합니다
  • 하위 호환되는 SQL 변경이 있으면 마이너 버전이 증가합니다
  • 바이너리만 변경되면 패치 버전이 증가합니다
설치가 완료되면 PostgreSQL은 두 가지 형태의 버전을 추적합니다.
  • 라이브러리 버전(PostgreSQL 18 이상에서는 PG_MODULE_MAGIC으로 정의됨)에는 전체 시맨틱 버전이 포함되며, pgch_version() 함수의 출력 또는 Postgres pg_get_loaded_modules() 함수에서 확인할 수 있습니다.
  • 확장 기능 버전(control file에 정의됨)에는 메이저 및 마이너 버전만 포함되며, pg_catalog.pg_extension 테이블, pg_available_extension_versions() 함수의 출력, 그리고 \dx pg_clickhouse에서 확인할 수 있습니다.
실제로 이는 예를 들어 패치 버전만 증가하는 릴리스, 즉 v0.1.0에서 v0.1.1로의 변경은 v0.1을 로드한 모든 데이터베이스에 적용되며, 업그레이드의 이점을 누리기 위해 ALTER EXTENSION을 실행할 필요가 없다는 뜻입니다. 반면 마이너 버전이나 메이저 버전이 증가하는 릴리스에는 SQL 업그레이드 스크립트가 함께 제공되며, 확장 기능이 포함된 기존의 모든 데이터베이스는 업그레이드의 이점을 누리기 위해 ALTER EXTENSION pg_clickhouse UPDATE를 실행해야 합니다.

DDL SQL 참고

다음 SQL DDL 표현식에서는 pg_clickhouse를 사용합니다.

CREATE EXTENSION

데이터베이스에 pg_clickhouse 확장 기능을 추가하려면 CREATE EXTENSION을 사용합니다:
특정 스키마에 설치하려면 WITH SCHEMA를 사용하세요(권장됨):

ALTER EXTENSION

pg_clickhouse를 변경하려면 ALTER EXTENSION을 사용합니다. 예시:
  • 새 릴리스의 pg_clickhouse를 설치한 후에는 UPDATE 절을 사용합니다:
  • 확장 기능을 새 스키마로 이동하려면 SET SCHEMA를 사용합니다:

DROP EXTENSION

데이터베이스에서 pg_clickhouse 확장 기능을 제거하려면 DROP EXTENSION을 사용합니다:
pg_clickhouse에 의존하는 객체가 있으면 이 명령은 실패합니다. 해당 객체도 함께 삭제하려면 CASCADE 절을 사용하십시오:

CREATE SERVER

ClickHouse 서버에 연결할 외부 서버를 생성하려면 CREATE SERVER를 사용합니다. 예시:
지원되는 옵션은 다음과 같습니다:
  • driver: 사용할 ClickHouse 연결 드라이버입니다. binary 또는 http여야 합니다. 필수입니다.
  • compression: binary driver용 네이티브 프로토콜 Compression 설정입니다. 값으로는 none, lz4, 또는 zstd 중 하나를 사용할 수 있습니다. 기본값은 lz4입니다. http driver에서는 무시됩니다.
  • dbname: 연결 시 사용할 ClickHouse 데이터베이스입니다. 기본값은 default입니다.
  • host: ClickHouse 서버의 호스트 이름입니다. 기본값은 localhost입니다;
  • port: ClickHouse 서버에 연결할 때 사용할 포트입니다. 기본값은 다음과 같습니다:
    • driver가 binary이고 host가 ClickHouse Cloud 호스트인 경우 9440
    • driver가 binary이고 host가 ClickHouse Cloud 호스트가 아닌 경우 9004
    • driver가 http이고 host가 ClickHouse Cloud 호스트인 경우 8443
    • driver가 http이고 host가 ClickHouse Cloud 호스트가 아닌 경우 8123
  • min_tls_version: TLS를 사용하는 연결에서 협상할 최소 TLS 프로토콜 버전입니다. 값으로는 TLSv1, TLSv1.1, TLSv1.2, 또는 TLSv1.3 중 하나를 사용할 수 있습니다. 기본값은 TLS 라이브러리 자체의 최소 버전입니다. 두 드라이버 모두에 적용됩니다.
  • secure: 연결에 사용할 TLS를 제어합니다. 값은 다음 중 하나입니다:
    • auto (기본값): host가 ClickHouse Cloud 호스트이거나 port가 보안 포트이면 TLS를 사용하고, 그렇지 않으면 plaintext를 사용합니다.
    • on (또는 true/yes/1): 항상 TLS를 사용합니다. 기본 port는 8443 (http) 또는 9440(binary)입니다.
    • off (또는 false/no/0): TLS를 사용하지 않습니다. 기본 port는 8123 (http) 또는 9000(binary)입니다.
  • encoding_check: ClickHouse String 및 JSON 값을 변환할 때 database encoding에서 유효하지 않은 문자를 처리하는 방식을 정의합니다. 값은 다음 중 하나입니다:
    • fail (기본값): 오류를 발생시킵니다
    • remove: 유효하지 않은 바이트를 제거합니다
    • replace: UTF-8 인코딩에서는 유효하지 않은 바이트를 유니코드 대체 문자(�)로 대체합니다. 다른 인코딩에서는 remove와 동일하게 동작합니다
    • truncate: 첫 번째 유효하지 않은 바이트 위치에서 텍스트를 잘라냅니다

ALTER SERVER

ALTER SERVER를 사용해 외부 서버를 수정합니다. 예시:
CREATE SERVER의 옵션과 동일합니다.

DROP SERVER

외부 서버를 삭제하려면 DROP SERVER를 사용합니다:
다른 객체가 서버에 종속되어 있으면 이 명령은 실패합니다. 해당 종속 항목도 함께 삭제하려면 CASCADE를 사용하십시오:

CREATE USER MAPPING

CREATE USER MAPPING을 사용하여 PostgreSQL 사용자를 ClickHouse 사용자에 매핑할 수 있습니다. 예를 들어, taxi_srv 외부 서버를 통해 연결할 때 현재 PostgreSQL 사용자를 원격 ClickHouse 사용자에 매핑하려면 다음과 같이 하십시오:
지원되는 옵션은 다음과 같습니다.
  • user: ClickHouse 사용자의 이름입니다. 기본값은 “default”입니다.
  • password: ClickHouse 사용자의 비밀번호입니다.

ALTER USER MAPPING

사용자 매핑 정의를 변경하려면 ALTER USER MAPPING을 사용하십시오:
옵션은 CREATE USER MAPPING과 동일합니다.

DROP USER MAPPING

사용자 매핑을 삭제하려면 DROP USER MAPPING을 사용합니다:

IMPORT FOREIGN SCHEMA

IMPORT FOREIGN SCHEMA를 사용하면 ClickHouse 데이터베이스에 정의된 모든 테이블을 PostgreSQL 스키마의 외부 테이블로 가져올 수 있습니다:
가져오기를 특정 테이블로 제한하려면 LIMIT TO를 사용하십시오:
테이블을 제외하려면 EXCEPT를 사용합니다:
pg_clickhouse는 지정된 ClickHouse 데이터베이스(위 예시의 “demo”)에 있는 모든 테이블 목록을 가져오고, 각 테이블의 컬럼 정의를 가져온 뒤 CREATE FOREIGN TABLE 명령을 실행해 외부 테이블을 생성합니다. 컬럼은 지원되는 데이터 타입과, 감지 가능한 경우 CREATE FOREIGN TABLE에서 지원하는 옵션을 사용해 정의됩니다. 유의해야 할 몇 가지 사항은 다음과 같습니다.
  • 가져온 컬럼은 Array 내부의 타입을 포함하여 ClickHouse 타입의 타입 수정자를 그대로 유지합니다. 예를 들어 Array(Decimal(12,6))는 numeric(12,6)[]로 가져옵니다.
  • Nullable 컬럼은 NOT NULL 없이 가져옵니다. 단, Array 내부의 Nullable은 예외입니다. PostgreSQL 배열은 항상 NULL 원소를 허용하기 때문입니다.
  • AggregateFunction 및 SimpleAggregateFunction 컬럼은 ClickHouse에서 어떻게 선언되었는지와 관계없이 NOT NULL 없이 가져옵니다. 자세한 내용은 상태 컬럼과 NOT NULL을 참조하십시오.
  • Tuple 컬럼은 text[]로 가져옵니다. Map 컬럼과 flatten_nested=0으로 생성된 Nested 컬럼은 text[][]로 가져옵니다. 이러한 변환이 이루어질 때마다 NOTICE가 출력됩니다. PostgreSQL의 record 의사 타입(pseudotype)으로는 테이블 컬럼을 정의할 수 없으므로, 각 튜플은 값의 배열로, 각 맵은 key-value 쌍의 2차원 배열로, 각 Nested 값은 행의 2차원 배열로 변환됩니다. 필드를 레코드로 읽으려면 컬럼을 해당 구조에 맞는 복합 타입의 배열로 변경하십시오. 예시는 Manual Type Mappings를 참조하십시오.
  • 정밀도가 6(마이크로초)을 초과하는 DateTime64 및 Time64 컬럼에서도 NOTICE가 출력됩니다. PostgreSQL은 정밀도를 최대 timestamp(6) 및 time(6)까지만 지원하기 때문입니다.
  • PostgreSQL에 대응하는 타입이 없는 컬럼 타입은 오류를 발생시킵니다. ClickHouse JSON 이전에 사용되던 레거시 Object('json') 타입도 여기에 해당합니다.
가져온 식별자의 대소문자 보존IMPORT FOREIGN SCHEMA는 가져오는 테이블 및 컬럼 이름에 quote_identifier()를 적용하며, 이때 대문자나 공백이 포함된 식별자는 큰따옴표로 묶습니다. 따라서 이러한 테이블 및 컬럼 이름은 PostgreSQL 쿼리에서 반드시 큰따옴표로 묶어야 합니다. 모두 소문자이고 공백 문자가 없는 이름은 따옴표로 묶지 않아도 됩니다.예를 들어, 다음과 같은 ClickHouse 테이블이 있다고 가정해 보겠습니다:
IMPORT FOREIGN SCHEMA는 다음과 같은 외부 테이블을 생성합니다:
따라서 쿼리에서도 적절히 따옴표를 사용해야 합니다. 예를 들면 다음과 같습니다.
다른 이름이나 모두 소문자인 이름(즉, 대소문자를 구분하지 않는 이름)으로 객체를 생성하려면 CREATE FOREIGN TABLE을 사용하십시오.

CREATE FOREIGN TABLE

ClickHouse 데이터베이스의 데이터를 쿼리할 수 있는 외부 테이블을 생성하려면 CREATE FOREIGN TABLE을 사용합니다:
지원되는 테이블 옵션은 다음과 같습니다.
  • database: 원격 데이터베이스의 이름입니다. 기본값은 외부 서버에 정의된 데이터베이스입니다.
  • table_name: 원격 테이블의 이름입니다. 기본값은 외부 테이블에 지정된 이름입니다.
  • engine: ClickHouse 테이블에 사용되는 [테이블 엔진]입니다. CollapsingMergeTree() 및 AggregatingMergeTree()의 경우, pg_clickhouse는 테이블에서 실행되는 함수 표현식에 매개변수를 자동으로 적용합니다.
각 컬럼의 원격 ClickHouse 데이터 타입에 맞는 데이터 타입을 사용하십시오. 지원되는 컬럼 옵션은 다음과 같습니다.
  • column_name: ClickHouse 쪽 컬럼의 이름입니다. 쿼리와 삽입을 deparse할 때 PostgreSQL 속성 이름보다 우선적으로 사용됩니다. 따옴표 없는 소문자 PostgreSQL 컬럼 이름을 대소문자를 구분하는 ClickHouse 컬럼에 매핑할 때 유용합니다. 예를 들면 다음과 같습니다.
  • AggregateFunction: AggregateFunction Type 컬럼에 적용되는 집계 함수의 이름입니다. 데이터 타입을 함수에 전달되는 ClickHouse 타입에 매핑하고, 적절한 컬럼 옵션으로 집계 함수 이름을 지정하면 pg_clickhouse가 해당 컬럼을 평가하는 집계 함수에 Merge를 자동으로 추가합니다. 상태 컬럼과 NOT NULL에 설명된 문제를 방지하려면 컬럼을 널 허용(nullable)으로 선언하십시오.
  • SimpleAggregateFunction: SimpleAggregateFunction Type 컬럼에 적용되는 집계 함수의 이름입니다. 데이터 타입을 함수에 전달되는 ClickHouse 타입에 매핑하고, 적절한 컬럼 옵션으로 집계 함수 이름을 지정하십시오.

상태 컬럼과 NOT NULL

AggregateFunction 및 SimpleAggregateFunction 컬럼은 널 허용(nullable)으로 유지하십시오. PostgreSQL 19는 NOT NULL 상태 컬럼에 대해 count(column)을 count(*)로 바꾸므로, 상태를 머지하지 않고 행 수를 세게 됩니다. 사용자별로 count 상태를 하나씩 저장하며, 각 상태가 1,000개의 이벤트로 생성된 ClickHouse 테이블을 예로 들어 보겠습니다.
NOT NULL을 사용하면 PostgreSQL이 상태(state)까지 개수에 포함하므로 유효하지 않은 집계 결과가 나옵니다:
NOT NULL이 없으면 pg_clickhouse는 countMerge()를 사용해 상태(state)를 머지하므로, 올바른 카운트 값인 1000을 반환합니다.
기존 외부 테이블에서 제약 조건을 삭제하려면 ALTER FOREIGN TABLE을 사용하십시오.
NOT NULL은 PostgreSQL에만 적용됩니다. 따라서 IMPORT FOREIGN SCHEMA는 상태 컬럼을 널 허용(nullable) 컬럼으로 가져옵니다.

ALTER FOREIGN TABLE

외부 테이블의 정의를 변경할 때는 ALTER FOREIGN TABLE을 사용합니다:
지원되는 테이블 및 컬럼 옵션은 CREATE FOREIGN TABLE과 동일합니다.

DROP FOREIGN TABLE

외부 테이블을 삭제할 때는 DROP FOREIGN TABLE을 사용합니다:
외부 테이블에 종속된 객체가 하나라도 있으면 이 명령은 실패합니다. 해당 객체도 함께 삭제하려면 CASCADE 절을 사용하십시오:

DML SQL 참고

아래의 SQL DML 표현식에서는 pg_clickhouse를 사용할 수 있습니다. 예시는 다음 ClickHouse 테이블(table)을 기준으로 합니다:

EXPLAIN

EXPLAIN 명령은 예상대로 작동하지만, VERBOSE 옵션을 사용하면 ClickHouse “Remote SQL” 쿼리가 출력됩니다:
이 쿼리는 “Foreign Scan” 실행 계획 노드를 통해 원격 SQL을 ClickHouse로 푸시다운합니다.

SELECT

다른 테이블과 마찬가지로 pg_clickhouse 테이블에서도 SELECT 문을 사용해 쿼리를 실행할 수 있습니다:
pg_clickhouse는 집계 함수를 포함해 가능한 한 많은 쿼리 실행을 ClickHouse로 푸시다운합니다. 푸시다운 범위를 확인하려면 EXPLAIN을 사용하십시오. 예를 들어 위 쿼리의 경우 모든 실행이 ClickHouse로 푸시다운됩니다
pg_clickhouse는 동일한 원격 서버에 있는 테이블 간 조인도 푸시다운합니다:
로컬 테이블과 조인하면 세심하게 튜닝하지 않는 한 비효율적인 쿼리가 생성될 수 있습니다. 이 예시에서는 원격 테이블 대신 nodes 테이블의 로컬 복사본을 만들고 이를 조인 대상으로 사용합니다:
이 경우 로컬 컬럼 대신 node_id를 기준으로 그룹화하면 더 많은 집계를 ClickHouse에서 처리하도록 할 수 있으며, 이후 lookup 테이블과 조인할 수 있습니다:
이제 “Foreign Scan” 노드는 node_id별 집계를 푸시다운하여, Postgres로 다시 가져와야 하는 행 수를 1000개(전체)에서 각 노드당 1개씩인 단 8개로 줄입니다.

파티션 테이블

PostgreSQL [파티션 테이블]은 로컬 파티션과 ClickHouse를 기반으로 하는 외래 파티션을 함께 사용할 수 있습니다. 일반적으로 오래된 데이터는 ClickHouse로 오프로드하고, 최근 데이터는 PostgreSQL에 유지합니다:
로컬 파티션에서 외래 파티션으로 데이터를 이동하는 방법은 offload-partition.sql 예시를 참조하십시오. 로컬 및 외래 파티션 모두에 걸친 집계에는 [파티션별 집계]가 필요하며, PostgreSQL에서는 기본적으로 비활성화되어 있습니다:
enable_partitionwise_aggregate를 활성화하면 PostgreSQL은 Append 아래에서 부분 집계를 수행한 후, 위의 최종 집계에서 이를 결합하여 결과를 생성합니다. pg_clickhouse는 외래 파티션의 부분 집계를 ClickHouse로 푸시다운합니다:

부분 집계가 푸시다운되는 경우

PostgreSQL은 부분 집계를 전이 상태로 나타내며, 최종 처리 단계에서 이를 여러 파티션에 걸쳐 결합합니다. pg_clickhouse는 파티션의 부분 집계를 ClickHouse 값으로 표현할 수 있을 때만 푸시다운할 수 있습니다.
  • 전이 상태가 이미 최종 값인 분해 가능한 집계 함수는 직접 푸시다운됩니다. 여기에는 count, sum, min, max, bool_and/every, bool_or, bit_and, bit_or, bit_xor가 포함됩니다.
  • **정수에 대한 avg**는 {count, sum} 상태를 배열로 푸시다운합니다.
  • **부동 소수점에 대한 avg, var_pop, var_samp, stddev_pop, stddev_samp**는 {N, sum, 제곱 편차의 합} 상태를 배열로 푸시다운합니다.
FILTER (WHERE …)는 이러한 집계 함수와 함께 푸시다운됩니다.

폴백되는 경우

전이 상태가 PostgreSQL의 불투명한 internal 유형인 집계 함수는 이식 가능한 표현이 없으므로, 외래 파티션에서 해당 행을 가져와 로컬에서 집계합니다. 여기에는 numeric에 대한 모든 집계와 avg(bigint), avg(interval)이 포함됩니다. DISTINCT, 순서 집합 및 가변 인수 집계 함수도 폴백됩니다.

PREPARE, EXECUTE, DEALLOCATE

v0.1.2부터 pg_clickhouse는 주로 PREPARE 명령으로 생성한 매개변수화된 쿼리를 지원합니다:
평소처럼 EXECUTE를 사용해 prepared statement를 실행하십시오:
pg_clickhouse는 평소와 같이 집계를 푸시다운하며, 이는 EXPLAIN 상세 출력에서 확인할 수 있습니다:
매개변수 자리표시자가 아니라 전체 날짜 값이 전송되었다는 점에 유의하십시오. 이는 PostgreSQL의 [PREPARE 참고 사항]에 설명된 대로 처음 5번의 요청에 해당합니다. 여섯 번째 실행부터는 ClickHouse의 {param:type} 형식 [쿼리 매개변수]를 전송합니다:
prepared statement을 해제하려면 DEALLOCATE를 사용합니다:

INSERT

원격 ClickHouse 테이블에 값을 삽입하려면 INSERT 명령을 사용하십시오:

COPY

원격 ClickHouse 테이블(table)에 여러 행(row)을 한 번에 삽입하려면 COPY 명령을 사용합니다:
⚠️ Batch API 제한 사항 pg_clickhouse는 아직 PostgreSQL FDW 배치 삽입 API를 지원하지 않습니다. 따라서 현재 COPY는 레코드를 삽입할 때 INSERT SQL 문을 사용합니다. 이 부분은 향후 릴리스에서 개선될 예정입니다.

LOAD

LOAD를 사용해 pg_clickhouse 공유 라이브러리를 로드합니다:
일반적으로 LOAD를 사용할 필요는 없습니다. Postgres는 해당 기능(함수, foreign table 등) 중 하나를 처음 사용할 때 pg_clickhouse를 자동으로 로드하기 때문입니다. LOAD pg_clickhouse가 유용할 수 있는 경우는, 이에 의존하는 쿼리를 실행하기 전에 SET으로 pg_clickhouse 매개변수를 설정해야 할 때입니다.

SET

SET를 사용해 pg_clickhouse의 사용자 지정 구성 매개변수를 설정합니다.

pg_clickhouse.session_settings

pg_clickhouse.session_settings 매개변수는 이후 쿼리에 설정할 [ClickHouse 설정]을 지정합니다. 예시:
기본값은
빈 문자열로 설정하면 ClickHouse 서버’s 설정으로 폴백됩니다 — 단, pushdown의 정확성은 이러한 기본값 중 일부에 따라 달라집니다. 외부 조인의 join_use_nulls 및 IN 계열의 transform_null_in (IN 및 NULL 의미 체계 참조).
구문은 하나 이상의 공백으로 구분된 쉼표 구분 키/값 쌍 목록입니다. 키는 [ClickHouse 설정]에 해당해야 합니다. 값에 포함된 공백, 쉼표, 백슬래시는 백슬래시로 이스케이프하세요:
또는 공백과 쉼표를 이스케이프하지 않으려면 작은따옴표로 묶인 값을 사용할 수 있습니다. 이중 따옴표를 사용하지 않으려면 [달러 인용] 사용을 고려하십시오:
가독성이 중요하고 많은 설정을 지정해야 한다면 여러 줄로 작성하십시오. 예시는 다음과 같습니다:
일부 설정은 pg_clickhouse 자체의 동작을 방해할 수 있는 경우 무시됩니다. 여기에는 다음이 포함됩니다:
  • date_time_output_format: http driver는 이 값을 “iso”로 요구합니다
  • format_tsv_null_representation: http driver는 기본값을 요구합니다
  • output_format_tsv_crlf_end_of_line: http driver는 기본값을 요구합니다
그 외에는 pg_clickhouse가 설정을 검증하지 않고, 모든 쿼리마다 이를 ClickHouse에 전달합니다. 따라서 각 ClickHouse 버전에서 제공하는 모든 설정을 지원합니다. pg_clickhouse.session_settings를 설정하기 전에 pg_clickhouse가 먼저 로드되어야 합니다. 이를 위해 [공유 라이브러리 사전 로드]를 사용하거나, 확장 기능에 포함된 객체 중 하나를 사용해 로드되도록 하면 됩니다.

pg_clickhouse.pushdown_regex

pg_clickhouse.pushdown_regex 매개변수는 pg_clickhouse가 정규식 함수와 연산자를 푸시다운할지 여부를 제어합니다. 기본값은 푸시다운을 수행하는 것이며, 푸시다운하지 않도록 하려면 이 매개변수를 false로 설정하십시오:
자세한 내용은 정규식을 확인하십시오.

ALTER ROLE

ALTER ROLE의 SET 명령을 사용하면 pg_clickhouse를 사전 로드하거나 특정 역할별로 매개변수를 SET할 수 있습니다:
pg_clickhouse의 사전 로드 및/또는 매개변수를 재설정하려면 ALTER ROLE의 RESET 명령을 사용하십시오:

사전 로드

모든 또는 거의 모든 Postgres 연결에서 pg_clickhouse를 사용해야 한다면, 이를 자동으로 로드하도록 [공유 라이브러리 사전 로드] 사용을 고려하십시오:

session_preload_libraries

PostgreSQL에 새 연결이 생성될 때마다 공유 라이브러리를 로드합니다:
서버를 다시 시작하지 않고도 업데이트 내용을 적용하는 데 유용합니다. 다시 연결만 하면 됩니다. ALTER ROLE을 통해 특정 사용자나 역할에 대해서도 설정할 수 있습니다.

shared_preload_libraries

시작 시 PostgreSQL 부모 프로세스에 공유 라이브러리를 로드합니다:
메모리 사용량과 각 세션의 로드 오버헤드를 줄이는 데 유용하지만, 라이브러리가 업데이트되면 클러스터를 다시 시작해야 합니다.

데이터 유형

이 표는 ClickHouse 데이터 유형과 PostgreSQL 데이터 유형 간의 권장 매핑을 보여줍니다. IMPORT FOREIGN SCHEMA는 이 매핑을 사용하여 적절한 유형 수정자(modifier)와 배열 차원을 도출합니다. 다른 PostgreSQL 유형을 선언하려면 CREATE FOREIGN TABLE을 사용하십시오. 추가 읽기 대상 열에는 PostgreSQL의 명시적 형변환 외에 binary 드라이버가 지원하는 변환이 나열되어 있습니다. 셀이 비어 있더라도 PostgreSQL의 명시적 형변환은 그대로 사용할 수 있습니다. 값은 대상 유형의 범위에 맞아야 합니다. 이 대상은 읽기에만 해당하며, 쓰기에는 별도의 변환 규칙이 적용됩니다. 모든 컬럼은 text, varchar 또는 다른 문자열 유형으로도 읽을 수 있습니다. 이때 값은 먼저 위의 PostgreSQL 유형으로 변환된 후, 해당 유형의 출력 함수를 거쳐 렌더링됩니다. 텍스트 유형으로 읽은 ClickHouse 문자열은 데이터베이스 인코딩 기준으로 검사되므로, PostgreSQL이 읽을 수 없는 바이트가 있으면 오류가 발생합니다. ClickHouse가 기록한 바이트를 그대로 읽으려면 String, FixedString, Enum 또는 JSON 컬럼을 BYTEA로 선언하십시오. 입력 호환 유형은 PostgreSQL 입력 함수를 사용하여 문자열을 읽을 수 있습니다. 복합 유형(composite type)은 필드 구성과 순서가 모두 일치해야 합니다. 튜플을 배열로 읽으려면 각 필드를 배열의 원소 유형으로 변환할 수 있어야 하며, 배열인 필드가 있어서는 안 됩니다. 배열로 읽을 때 Map은 키-값 쌍마다 1개의 행을, Nested는 중첩 레코드마다 1개의 행을 사용합니다. 튜플을 box로 읽으려면 Point 2개를 제공하고, circle로 읽으려면 Point 1개와 반지름을, line으로 읽으려면 계수 3개를 제공하십시오. 추가 참고 사항과 세부 정보는 아래와 같습니다.

유형 강제 변환(Type Coercion)

binary 드라이버에서는 대체 스칼라 유형에 대해 가능한 경우 PostgreSQL의 명시적 형변환을 사용하며, 배열 원소는 선언된 원소 유형으로 변환됩니다. 지원되지 않는 변환이나 범위를 벗어난 값은 오류를 발생시킵니다. 두 드라이버 모두 ClickHouse Interval 유형을 smallint, integer, 또는 bigint에 매핑하면 해당 단위의 개수로 읽고 쓸 수 있습니다. 예를 들어 IntervalDay 값 3은 정수 3에 매핑됩니다. IntervalNanosecond를 bigint에 매핑하면 나노초 정밀도가 유지되지만, interval에 매핑하면 마이크로초 단위로 잘립니다.

BYTEA

ClickHouse는 PostgreSQL의 BYTEA 유형에 해당하는 유형을 제공하지 않지만, [String] 유형에 임의의 바이트를 저장할 수 있습니다. 일반적으로 ClickHouse 문자열은 PostgreSQL의 [TEXT]에 매핑하고, 바이너리 데이터를 사용하는 경우에는 BYTEA에 매핑하십시오. 예시:
마지막 SELECT 쿼리의 출력 결과는 다음과 같습니다:
[TEXT] 컬럼을 사용하는 외부 테이블은 일반적으로 이러한 값을 텍스트로 읽을 수 없습니다. pg_clickhouse가 ClickHouse 바이트가 데이터베이스 인코딩에 맞는지 검사하기 때문입니다:
출력 결과:
다이제스트(digest)에는 임의의 바이트(arbitrary bytes)가 담기며, 이러한 바이트가 유효한 텍스트를 이루는 경우는 드뭅니다. 또한 PostgreSQL은 nul을 예약 문자로 사용하므로, nul이 포함된 ClickHouse 문자열은 [TEXT] 컬럼으로 읽을 수 없습니다. [TEXT] 컬럼에 이진 값을 삽입하면 예상대로 성공적으로 작동합니다:
이제 텍스트 컬럼에 올바른 값이 출력됩니다:
하지만 BYTEA로 읽으면 그렇지 않습니다:
FixedString(N) 컬럼은 짧은 값의 나머지 부분을 nul 바이트로 채웁니다. 텍스트 컬럼은 이렇게 끝에 채워진 패딩을 제거하지만, BYTEA 컬럼은 모든 바이트를 그대로 유지합니다.
일반적으로 인코딩된 문자열에는 [TEXT] 컬럼만 사용하고, BYTEA 컬럼은 바이너리 데이터에만 사용하며, 두 타입을 서로 바꿔 사용해서는 안 됩니다.

복합 타입

배열

ClickHouse [Array]는 동일한 의미 체계를 유지하면서 PostgreSQL 배열에 직접 매핑됩니다. 주요 차이점은 Postgres 다차원 배열에서는 배열 표현식의 차원이 모두 일치해야 한다는 점입니다. [[1], [2,3]]처럼 차원이 서로 다른 ClickHouse 배열을 읽으려고 하면 오류가 발생합니다. 배열 인덱스 액세스는 다차원 인덱스 액세스를 포함하여 필요에 따라 푸시다운됩니다. 예시:
배열 슬라이스도 [arraySlice] 함수를 통해 푸시다운(push down)됩니다. 단, 다차원 슬라이스 액세스는 아직 지원되지 않습니다:

Map

PostgreSQL에는 ClickHouse [Map] 타입에 대응하는 타입이 없습니다. 따라서 pg_clickhouse는 [Map] 컬럼을 text[][]로 매핑하며, 각 키-값 쌍을 개별 배열로 표현합니다. IMPORT FOREIGN SCHEMA도 이 매핑을 사용합니다. 맵을 배열 형태로 INSERT할 수도 있습니다. 예시는 다음과 같습니다.
각 중첩 배열에는 정확히 2개의 텍스트 값이 포함되어야 합니다. 해당 ClickHouse 키 또는 값 타입과 호환되지 않는 값이 있으면 오류가 발생합니다.
Map을 삽입하려면 ClickHouse 서버에서 컬럼 타입 정보를 가져오는 binary 드라이버가 필요합니다. http 드라이버는 컬럼 타입 정보를 가져오지 않으므로, 적절한 값을 포맷하고 삽입하는 데 필요한 정보가 없습니다.

Tuple

마찬가지로 ClickHouse [Tuple] 컬럼은 text[]에 매핑되며, binary 드라이버를 통한 INSERT를 지원합니다. IMPORT FOREIGN SCHEMA는 이러한 매핑을 수행하면 NOTICE를 출력합니다.

Nested

기본적으로 ClickHouse는 Nested 컬럼을 필드마다 하나의 Array 컬럼으로 분할합니다(flatten_nested=1). IMPORT FOREIGN SCHEMA는 ClickHouse의 system.columns 카탈로그에서 이 컬럼들을 읽어 각각 별도의 PostgreSQL 배열 컬럼으로 생성하며, 이때 items.a, items.b처럼 점이 포함된 이름을 그대로 유지합니다. 예를 들어, 다음과 같은 외부 테이블이 있다고 가정합니다.
이를 가져온 스키마에는 컬럼이 2개가 아닌 3개 있습니다:
중첩 컬럼(nested columns)은 다음과 같이 컬럼명을 큰따옴표로 감싸서 쿼리하십시오. 예:
또한 배열 첨자 구문을 비롯한 일반적인 배열 기능을 사용하여 WHERE 절에서 값을 필터링할 수 있습니다:
flatten_nested=0으로 생성된 [Nested] 컬럼은 중첩된 행 하나당 항목 하나로 구성된 배열에 매핑됩니다. 각 배열 항목에는 해당 행의 값이 담겨 있습니다.
이제 생성된 스키마는 다음과 같습니다:
중첩된 레코드는 ClickHouse 컬럼에 정의된 각 유형에 맞게 형식화된 텍스트 값을 사용하여 2차원 배열로 구성하십시오. 이 예시의 c2 Nested(id Int64, name String)은 다음과 같이 구성됩니다:
그러나 Nested 유형을 대상으로 하는 text[][] 컬럼의 푸시다운(Pushdown)은 실패합니다.
이는 pg_clickhouse가 ClickHouse 배열 컬럼을 기반으로 하는 텍스트 배열 컬럼과 Nested 컬럼을 기반으로 하는 텍스트 배열 컬럼을 구분할 수 없어, 이를 ClickHouse의 Nested 구문으로 재작성할 수 없기 때문입니다. 다만 이러한 항목은 일치하는 복합 유형(composite type)의 배열로도 매핑할 수 있으며(자세한 내용은 수동 유형 매핑 참조), 이 경우 복합 유형의 필드 이름이 Nested 필드 이름과 동일하기만 하면 푸시다운(pushdown)이 동작합니다.

수동 유형 매핑

IMPORT FOREIGN SCHEMA는 범용 PostgreSQL 유형을 사용합니다. 예를 들어, 다음과 같이 [Enum], [Tuple], Map 및 평탄화되지 않은(unflattened) [Nested] (flatten_nested = 0) 컬럼을 사용하는 ClickHouse 테이블이 있다고 가정해 보겠습니다.
구조를 유지하거나 값을 제한하려면 PostgreSQL 복합(composite) 유형 또는 열거형(enum) 유형을 정의한 다음 외부 테이블(foreign table)을 직접 생성하십시오:
푸시다운(pushdown) 시 올바른 이름이 지정되도록 enum 레이블과 복합 유형(composite type)의 필드 이름은 항상 ClickHouse의 enum 레이블 및 Nested 또는 Tuple 필드 이름과 동일하게 지정하십시오.
복합 유형의 필드 순서와 유형은 ClickHouse 선언과 일치시켜야 합니다. [Map]의 키와 값은 각각 첫 번째 필드와 두 번째 필드가 됩니다(이 예시에서는 key와 value). Nested와 Map은 복합 유형의 배열이 되고, Tuple은 단일 복합 유형 값이 됩니다.
물론 복합 유형(composite type)의 필드 이름도 사용할 수 있으며, 먼저 SELECT 목록에서는 다음과 같이 사용합니다:
또한 WHERE 절의 [Nested] 유형에도 필드 이름이 동일하기만 하면 적용됩니다:
이러한 복합 유형을 사용한 INSERT는 아직 지원되지 않습니다.

Function 및 연산자 참고

함수

이 함수들은 ClickHouse 데이터베이스를 쿼리하기 위한 인터페이스를 제공합니다.

clickhouse_server_version

지정한 외부 서버의 ClickHouse 서버 버전을 major.minor.patch 형식으로 반환합니다. 필요한 경우 서버’s 옵션과 현재 사용자의 사용자 매핑을 사용하여 연결합니다:
네이티브 프로토콜 연결 핸드셰이크에서 버전을 가져오거나, HTTP를 통해 단일 SELECT version() 쿼리로 가져온 뒤 연결이 유지되는 동안 캐시합니다.

clickhouse_query

이미 구성된 외부 서버에서 쿼리를 실행하고, 각 ClickHouse 결과 컬럼을 컬럼 정의 목록에 지정된 PostgreSQL 유형에 매핑하여 해당 행을 릴레이션으로 반환합니다. 서버의 driver, 자격 증명, 데이터베이스, 연결 캐시를 재사용합니다. 첫 번째 인수는 CREATE SERVER로 생성한 서버 이름입니다. 컬럼 정의 목록 (AS name(col type, ...))은 필수입니다. PostgreSQL은 행을 가져오기 전에 결과 구조를 알아야 하며, 이 구조는 쿼리가 반환하는 컬럼과 일치해야 합니다. 값은 외부 테이블 컬럼과 동일한 방식으로 ClickHouse에서 선언된 유형으로 변환됩니다. DDL처럼 결과를 반환하지 않는 SQL 문은 선언할 항목이 없으므로, 대신 clickhouse_perform을 사용하여 실행하십시오. 기본적으로 어떤 역할에도 EXECUTE 권한이 없습니다. 역할이 이 함수를 사용할 수 있도록 GRANT하십시오.

clickhouse_perform

이미 구성된 외부 서버에 대해 SQL 문을 실행하고 결과는 모두 버립니다. DDL처럼 행을 반환하지 않아 clickhouse_query에서 선언할 결과 구조가 없는 SQL 문에 사용하십시오. 서버는 clickhouse_query와 동일한 방식으로 확인하며, 해당 함수의 driver, 자격 증명, 데이터베이스 및 연결 캐시를 재사용합니다. 프로시저이므로 SELECT가 아닌 CALL로 호출해야 하며, 행을 반환하지 않습니다. 기본적으로 어떤 역할에도 EXECUTE 권한이 없습니다. 프로시저 사용을 허용하려면 역할에 GRANT하십시오.

푸시다운 함수

pg_clickhouse는 조건식(HAVING 및 WHERE 절)에 사용되는 PostgreSQL 내장 함수 일부를 ClickHouse로 푸시다운합니다. 이 함수 집합은 다음과 같이 ClickHouse의 대응 함수에 매핑됩니다:

푸시다운 연산자

IN 및 NULL 의미 체계

ClickHouse는 IN을 2값 논리로 평가합니다. 즉, NULL이 관련된 경우에도 프로브에서 일치 항목을 찾지 못하면 0을 반환하는 반면 PostgreSQL은 NULL을 반환합니다. PostgreSQL 의미 체계를 보존하기 위해 pg_clickhouse는 상수 목록 또는 배열에 대한 IN 계열(IN, NOT IN, = ANY, = ALL, <> ANY, <> ALL)을 무조건 푸시다운합니다. 프로브나 배열 원소가 NULL일 수 없음을 증명할 수 있으면 네이티브 또는 저비용 형식을 사용하고, 그렇지 않으면 런타임에 NULL 값을 확인하는 보호된 CASE 형식을 사용합니다. 이를 통해 SELECT 목록이나 GROUP BY와 같은 값 위치를 비롯한 모든 컨텍스트에서 PostgreSQL의 정확한 3값 결과(TRUE, FALSE, NULL)를 계산합니다. 널 허용 컬럼에 대한 NOT IN (SELECT ...) 필터도 푸시다운되며, PostgreSQL 동작을 유지하도록 보정 가드가 추가된 형태로 역파싱됩니다. 즉, NULL을 포함하는 Set은 모든 행을 제외하고, NULL 프로브는 빈 Set에 대해서만 통과합니다. NOT NULL 선언으로 불필요함을 증명할 수 있으면 각 가드는 생략됩니다. 위의 배열 형식과 달리 이 가드는 일반 필터 조건(또는 NOT 아래)에서만 적용됩니다. 값 위치의 IN (SELECT ...) 및 그룹화되거나 집계된 하위 쿼리 본문은 여전히 푸시다운하지 않습니다. 컬럼을 NOT NULL로 선언하면 더 저렴한 가드 없는 형식을 전송할 수 있으므로 푸시다운을 극대화할 수 있습니다. IMPORT FOREIGN SCHEMA는 Nullable이 아닌 ClickHouse 컬럼에 대해 이를 자동으로 수행합니다. 이 증명은 NULL이 아닌 상수, NOT NULL 컬럼 및 이들에 대한 기본 산술 연산(+, -, *, 단항 -)을 대상으로 합니다. 이 규칙은 ClickHouse의 기본값인 transform_null_in = 0을 전제합니다. pg_clickhouse는 ClickHouse 서버 프로필이 이 값을 암묵적으로 변경하지 못하도록 pg_clickhouse.session_settings 매개변수의 기본값을 통해 모든 쿼리에 이를 설정합니다. transform_null_in = 1로 설정하면 푸시다운된 모든 IN의 의미 체계가 깨집니다.

사용자 지정 함수

pg_clickhouse로 생성된 이러한 사용자 지정 함수는 PostgreSQL에 대응하는 기능이 없는 일부 ClickHouse 함수에 대해 원격 쿼리 푸시다운을 제공합니다. 이 함수들 중 하나라도 pushdown되지 않으면 예외를 발생시킵니다.

확장 기능 푸시다운

pg_clickhouse는 일부 핵심 확장 기능과 서드파티 확장 기능의 함수를 인식하여, 해당 ClickHouse 함수로 푸시다운합니다.

re2

모든 [re2 확장 기능] 연산자 및 함수는 ClickHouse 함수에 1:1로 푸시다운됩니다:

intarray

다음 [intarray] 함수 1개가 ClickHouse로 푸시다운됩니다:

fuzzystrmatch

다음 2개의 [fuzzystrmatch] 함수는 ClickHouse로 푸시다운됩니다:

pgcyrpto

  • digest(text, text) 및 digest(bytea, text): 알고리즘이 상수 md5, sha1, sha224, sha256, sha384, sha512 중 하나인 경우(대소문자 구분 없음) 이에 대응하는 ClickHouse 해시 함수로 변환됩니다.

푸시다운 캐스트

pg_clickhouse는 호환되는 데이터 타입에 대해서는 CAST(x AS bigint)와 같은 캐스트를 푸시다운합니다. 호환되지 않는 타입에서는 푸시다운이 실패합니다. 이 예시에서 x가 ClickHouse UInt64라면 ClickHouse는 해당 값의 캐스트를 거부합니다. 호환되지 않는 데이터 타입으로의 캐스트도 푸시다운할 수 있도록 pg_clickhouse는 다음 함수를 제공합니다. 이 함수들이 푸시다운되지 않으면 PostgreSQL에서 예외를 발생시킵니다.

푸시다운 집계 함수

다음 PostgreSQL 집계 함수는 ClickHouse로 푸시다운됩니다.

사용자 지정 집계 함수

pg_clickhouse가 생성한 이러한 사용자 지정 집계 함수는 PostgreSQL에 대응하는 기능이 없는 일부 ClickHouse 집계 함수에 대해 원격 쿼리 푸시다운을 제공합니다. 이 함수들 중 하나라도 푸시다운할 수 없으면 예외를 발생시킵니다.

푸시다운 정렬된 집합 집계 함수

이 [정렬된 집합 집계 함수]는 직접 인수를 매개변수로, ORDER BY 표현식을 인수로 전달하는 방식으로 ClickHouse [매개변수화된 집계 함수]에 대응됩니다. 예를 들어, 다음 PostgreSQL 쿼리는:
다음 ClickHouse 쿼리로 변환됩니다:
기본값이 아닌 ORDER BY 접미사 DESC 및 NULLS FIRST는 지원되지 않으며, 사용하면 오류가 발생합니다.

사용자 정의 정렬된 집합 집계 함수

pg_clickhouse에서 생성된 이러한 사용자 정의 [정렬된 집합 집계 함수]는 일부 ClickHouse [매개변수화된 집계 함수]에 대한 원격 쿼리 푸시다운을 제공합니다. 이러한 함수 중 푸시다운할 수 없는 함수가 있으면 예외가 발생합니다.

사용자 정의 정렬된 집합 집계 함수

pg_clickhouse에서 제공하는 이러한 사용자 정의 [정렬된 집합 집계 함수]는 일부 ClickHouse [매개변수화된 집계 함수]에 대한 원격 쿼리 푸시다운을 지원합니다. 이 함수들을 푸시다운할 수 없으면 예외가 발생합니다.

푸시다운 윈도우 함수

다음 PostgreSQL [윈도우 함수]는 해당되는 경우 프레임 사양을 포함한 OVER (PARTITION BY ... ORDER BY ...) 절과 함께 ClickHouse로 푸시다운됩니다. 순위 함수(row_number, rank, dense_rank, ntile, cume_dist, percent_rank)는 ClickHouse에서 이러한 함수의 프레임 사양을 허용하지 않으므로 푸시다운 시 프레임 절을 생략합니다.

호환성 관련 참고 사항

정규식

pg_clickhouse.pushdown_regex가 true일 때(기본값) pg_clickhouse는 정규식을 ClickHouse의 대응 표현식으로 푸시다운하며, 기본적인 수준의 호환성을 보장하기 위해 노력합니다. 다만 두 시스템 간 차이점과 pg_clickhouse가 이를 어떻게 처리하는지는 숙지해야 합니다.
  • PostgreSQL은 [POSIX Regular Expressions]를 지원하고 ClickHouse는 [RE2 Regular Expressions][RE2]를 지원합니다. 동작 방식의 차이에 유의하십시오. 정규식이 ClickHouse에서 평가되는 경우(예: WHERE 절)에는 RE2를 사용하고, Postgres에서 평가되는 경우(예: SELECT 절)에는 POSIX를 사용하십시오.
  • pg_clickhouse는 [Postgres 플래그]를 (?) 안의 ClickHouse 정규식 앞에 붙여 전달합니다. 예시는 다음과 같습니다:
    다음과 같이 바뀝니다
  • 둘 다 지원하므로 ClickHouse에서 평가할 때 사용할 수 있는 플래그는 다음뿐입니다: RE2에서는 이러한 플래그만 지원하므로 다른 [Postgres 플래그]는 사용하지 마십시오.
  • 이 표는 새 줄 문자와 줄 끝을 매칭할 때 다양한 플래그(및 s와 동일한, 플래그를 지정하지 않은 경우)의 영향을 요약합니다. Postgres에서는 m과 p가 부정 문자 클래스([^xyz])가 새 줄 문자와 매칭되는 것을 막지만, ClickHouse의 해당 플래그는 그렇지 않다는 점에 유의하십시오. 그 외의 동작은 ClickHouse와 Postgres에서 동일합니다:
  • 정규식 함수에 전달된 다른 플래그가 있으면 함수는 푸시다운되지 않습니다.
  • 예외는 regexp_replace()로, g 플래그도 지원합니다. g가 설정되면 pg_clickhouse는 replaceRegexpOne() 대신 replaceRegexpAll()을 사용하고, 다른 플래그를 앞에 추가하기 전에 g 플래그를 제거합니다.
  • Postgres regexp_replace()의 대체 인수는 전체 일치를 가리킬 때 \&를 지원하지만, ClickHouse에서는 전체 일치에 \0를 사용합니다. 함수가 ClickHouse로 푸시다운되는 경우 반드시 \0를 사용하십시오.
  • 일치하는 항목이 없으면 Postgres regexp_match는 NULL을 반환하지만, 푸시다운되는 표현식은 빈 배열을 반환합니다. 반환 값을 호환되게 비교하려면 COALESCE()를 사용해 NULL 대신 빈 배열을 반환하게 하십시오. 예시는 다음과 같습니다:
모호함을 완전히 피하려면 pg_clickhouse.pushdown_regex를 설정하여 Postgres 정규식이 ClickHouse로 푸시다운되지 않도록 하고, pg_clickhouse가 ClickHouse 호환 [RE2] 정규식의 직접 푸시다운을 지원하는 [re2 확장 기능]을 사용하는 것을 고려하십시오.

to_char()

timestamp 및 timestamp with time zone에 대한 PostgreSQL [to_char()]는 포맷 인수가 비-NULL 문자열 상수이고, 그 안의 모든 PostgreSQL 키워드에 바이트 단위까지 동일한 ClickHouse 대응 항목이 있는 경우에만 ClickHouse [formatDateTime]으로 푸시다운됩니다. 포맷이 동적이거나 지원되지 않는 키워드 또는 수정자를 포함하는 경우에는 해당 호출은 PostgreSQL에서 로컬로 평가됩니다. pg_clickhouse는 부분 변환을 절대 푸시다운하지 않으므로 출력은 호환성을 유지합니다. numeric, interval 및 기타 타임스탬프가 아닌 타입에 대한 2인수 to_char() 형태는 절대로 푸시다운되지 않습니다. ClickHouse [formatDateTime]은 날짜-시간 값만 포맷합니다.

번역된 키워드

인용된 텍스트와 리터럴

"..."로 감싼 텍스트는 있는 그대로 전달되며, 리터럴 %는 ClickHouse의 지정자 접두사(prefix)를 이스케이프하기 위해 %%로 두 번 써야 합니다. 따옴표 밖의 \"도 리터럴 "로 그대로 전달됩니다. "..." 내부에서는 백슬래시가 "에만 이스케이프 문자로 작동하며, 다른 백슬래시 시퀀스는 리터럴 텍스트로 처리됩니다.

작성자

David E. Wheeler 저작권 (c) 2025-2026, ClickHouse [Array] https://clickhouse.com/docs/reference/data-types/array “ClickHouse 문서: Array(T)” [Map]: https://clickhouse.com/docs/sql-reference/data-types/map “ClickHouse 문서: Map” [Tuple]: https://clickhouse.com/docs/reference/data-types/tuple “ClickHouse 문서: Tuple(T1, T2, …)” [Nested]: https://clickhouse.com/docs/sql-reference/data-types/nested-data-structures/nested “ClickHouse 문서: Nested” [Enum]: https://clickhouse.com/docs/reference/data-types/enum “ClickHouse 문서: Enum” [String]: /reference/data-types/string “ClickHouse 문서: String” [TEXT]: https://www.postgresql.org/docs/current/datatype-character.html “PostgreSQL 문서: 문자 데이터 타입” [window functions]: https://www.postgresql.org/docs/current/functions-window.html “PostgreSQL 문서: 윈도우 함수” [POSIX Regular Expressions]: https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-POSIX-REGEXP “PostgreSQL 문서: POSIX 정규식” [Postgres flags]: https://www.postgresql.org/docs/current/functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE “PostgreSQL 문서: ARE 내장 옵션 문자” [RE2]: https://github.com/google/re2/wiki/Syntax “RE2 구문” [re2 extension]: https://github.com/ClickHouse/pg&#95;re2 “pg_re2: RE2를 사용하는 ClickHouse 호환 정규식 함수” [intarray]: https://www.postgresql.org/docs/current/intarray.html “PostgreSQL 문서: intarray” [fuzzystrmatch]: https://www.postgresql.org/docs/current/fuzzystrmatch.html “PostgreSQL 문서: fuzzystrmatch” [to_char()]: https://www.postgresql.org/docs/current/functions-formatting.html “PostgreSQL 문서: 데이터 타입 서식 함수” [formatDateTime]: /reference/functions/regular-functions/date-time-functions#formatDateTime “ClickHouse 문서: formatDateTime”