pg_clickhouse 0.11.0 讓壞掉的 UTF-8 不再中斷查詢
ClickHouse Blog(David Wheeler)· 2026-09-30
pg_clickhouse v0.11.0 與 chdb v0.1.2 把 ClickHouse 的 interval、JSON、Nested、Tuple、Map 等型別,改成能直接對應到 Postgres 原生型別,並新增 check_encoding 選項處理無效的 UTF-8 位元組。這兩個擴充都讓 Postgres 成為 ClickHouse 的查詢入口,過去遇到這些型別或編碼問題,查詢只能報錯或手動繞路。
兩個版本於 2026-09-30 同日發布,詳見 pg_clickhouse v0.11.0 與 chdb v0.1.2。
原本的問題
ClickHouse 的資料裡只要有一個無效的 UTF-8 位元組,Postgres 端就無法把它當成合法 text 收下。部落格把 fail 列為 check_encoding 的預設行為,也就是直接報錯。
型別方面,Interval、參數化 JSON、未攤平的 Nested、Tuple 與 Map,都缺少與 Postgres 型別的明確對應。使用者只能在 ClickHouse 端先轉型,再讓 Postgres 查詢轉換後的結果。
核心改動
編碼處理:外部伺服器現在可設定 check_encoding,共有四種值。
fail:預設值,遇到無效位元組即報錯remove:移除無效位元組replace:換成 Unicode 替代字元truncate:在第一個無效位元組處截斷文字
-- 之前:遇到壞位元組只能 fail
ALTER SERVER ch_server_name OPTIONS (ADD check_encoding 'replace');
-- chdb 匯入 CSV 時同樣可指定
CREATE TABLE logs () WITH (
copy_from = 's3://chdb-lakedata-public/logs/logs-2026-08-26.csv',
format = 'CSVWithNames',
check_encoding = 'replace'
);Interval 對應:IntervalMillisecond、IntervalDay 等型別會匯入成 Postgres 的 interval 欄位。含 interval 的條件也能下推,文中的範例 start_at + duration < date_trunc('day', now()) 會被改寫成遠端的 toStartOfDay(now64()) 比較。
Nested 與 JSON:參數化的 JSON(id UInt32, name String, ...) 欄位可以建立。當 ClickHouse 表設定 flatten_nested = 0 時,Nested 欄位預設對應成多維 text[][],也可以改宣告成 Postgres 複合型別陣列。
CREATE TYPE goal_type AS (serial bigint, order_id text);
ALTER FOREIGN TABLE visits ALTER goals TYPE goal_type[];
-- 結果:{"(1,xx)","(2,yy)"}型別對照
| ClickHouse | PostgreSQL |
|---|---|
UInt64 | numeric(20,0) |
Int128 | numeric(39,0) |
Int256 | numeric(77,0) |
BFloat16 | float4 |
Tuple(...) | text[] |
Map(K,V) | text[][] |
Polygon | polygon[] |
影響範圍
用 Postgres 查 ClickHouse 日誌的團隊:外部資料常含壞編碼,可在 foreign server 上加 check_encoding 'replace'。但 replace、remove 與 truncate 都會改動原始內容,需要逐字比對的稽核欄位要保留預設的 fail。
升級前要檢查的項目:這一版移除了 clickhouse_raw_query()(部落格記載於 v0.10.0 移除),改用 clickhouse_query(server, sql) 與 CALL clickhouse_perform(server, sql)。同時停止支援 PostgreSQL 13。仍在 PG 13 的環境無法升級,用到舊函式的腳本會直接失敗。
另外新增了 SHA-224、SHA-256、SHA-384、SHA-512 與 pgcrypto digest() 的下推。部落格未公布效能數字,是否變快需自行量測。