描述
快速开始
用法
版本策略
- API 发生变更时,递增主版本号
- SQL 发生向后兼容的变更时,递增次版本号
- 仅有 binary 变更时,递增补丁版本号
- 库版本 (在 PostgreSQL 18 及以上版本中由
PG_MODULE_MAGIC定义) 包含完整的语义化版本号,可在pgch_version()函数的输出或 Postgrespg_get_loaded_modules()函数中查看。 - 扩展版本 (在控制文件中定义) 仅包含主版本号和次版本号,可在
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 参考
CREATE EXTENSION
WITH SCHEMA 将其安装到指定的 schema 中 (推荐) :
ALTER EXTENSION
-
安装 pg_clickhouse 的新 release 后,使用
UPDATE子句: -
使用
SET SCHEMA将该扩展移动到新的 schema:
DROP EXTENSION
CASCADE 子句将它们一并删除:
CREATE SERVER
driver:要使用的 ClickHouse 连接驱动程序,可以是 “binary” 或 “http”。必填。compression:binary driver 的 native 协议压缩,可选值为 “none”、“lz4” 或 “zstd”。默认为 “lz4”。http 驱动会忽略此选项。dbname:连接时使用的 ClickHouse 数据库。默认为 “default”。fetch_size:HTTP streaming 的近似批次大小 (以字节为单位) 。批次 按行边界拆分。默认为50000000(50 MB) 。0会禁用 streaming 并缓冲整个响应。foreign table 可以覆盖此 值。host:ClickHouse server 的主机名。默认为 “localhost”;port:连接到 ClickHouse server 时使用的端口。默认值 如下:- 如果
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”) 。
ALTER SERVER
DROP SERVER
CASCADE 还会
一并删除这些依赖对象:
CREATE USER MAPPING
taxi_srv 外部服务器 连接时,可将当前 PostgreSQL 用户映射为远程 ClickHouse 用户:
user:ClickHouse 用户名。默认为 “default”。password:ClickHouse 用户的密码。
ALTER USER MAPPING
DROP USER MAPPING
IMPORT FOREIGN SCHEMA
LIMIT TO 将导入限制到特定表:
EXCEPT 排除这些表:
CREATE FOREIGN TABLE
database:远程 database 的名称。默认使用为 外部服务器 定义的 database。fetch_size:HTTP streaming 的近似批次大小 (以字节为单位) 。会覆盖 server 级别的fetch_size。默认值为50000000(50 MB) 。0会禁用 流式传输并缓冲完整响应。table_name:远程表的名称。默认使用为 foreign table 指定的名称。engine:ClickHouse 表使用的[表引擎]。对于CollapsingMergeTree()和AggregatingMergeTree(),pg_clickhouse 会自动将参数应用于在该表上执行的函数表达式。
-
column_name:ClickHouse 端的列名,在反解析查询和 插入语句时,会优先使用该名称而不是 PostgreSQL attribute 名称。 这对于将未加引号的小写 PostgreSQL 列名映射到 区分大小写的 ClickHouse 列很有用,例如: -
AggregateFunction:应用于 AggregateFunction Type 列的聚合函数名称。将数据类型映射为传递给该函数的 ClickHouse 类型,并通过相应的列选项指定 聚合函数名称,pg_clickhouse 会自动在计算该列的聚合函数后追加Merge。 -
SimpleAggregateFunction:应用于 SimpleAggregateFunction Type 列的聚合函数名称。将数据类型映射为 传递给该函数的 ClickHouse 类型,并通过相应的 列选项指定聚合函数名称。
ALTER FOREIGN TABLE
DROP FOREIGN TABLE
CASCADE 子句也会将它们一并删除:
DML SQL 参考
EXPLAIN
VERBOSE 选项会触发输出
ClickHouse 的 “Remote SQL” 查询:
SELECT
nodes 表的一个本地副本,并与它连接,而不是连接远程表:
node_id 而不是本地列分组,将更多聚合下推到 ClickHouse,然后再
与查找表进行 join:
node_id 下推聚合,将需要从 Postgres 拉回的行数从 1000 行 (全部行) 减少到仅 8 行,即每个节点 1 行。
PREPARE, EXECUTE, DEALLOCATE
{param:type} 风格的[查询参数]:
参数:
INSERT
COPY
⚠️ 批次 API 的限制 pg_clickhouse 尚未支持 PostgreSQL FDW 的批次 insert API。因此,COPY 目前通过 INSERT 语句 插入记录。后续版本将对此进行改进。
LOAD
SET
pg_clickhouse.session_settings
pg_clickhouse.session_settings 参数用于配置在后续查询中要设置的 [ClickHouse
设置]。示例:
join_use_nulls 1, group_by_use_nulls 1, final 1。将其设为空
字符串即可恢复为 ClickHouse server 的设置。
date_time_output_format:http 驱动要求其为 “iso”format_tsv_null_representation:http 驱动要求使用默认值output_format_tsv_crlf_end_of_line:http 驱动要求使用默认值
pg_clickhouse.session_settings;可以使用[共享库预加载],或者
直接使用该扩展中的某个对象以确保其被加载。
pg_clickhouse.pushdown_regex
pg_clickhouse.pushdown_regex 参数用于控制 pg_clickhouse
是否对正则表达式函数和操作符执行下推。默认情况下会执行下推;
将此参数设置为 false 可阻止下推:
ALTER ROLE
SET 命令,可为特定角色预加载 pg_clickhouse,
和/或 SET 其参数:
RESET 命令重置 pg_clickhouse 的预加载
和/或相关参数:
预加载
session_preload_libraries
数据类型
| ClickHouse | PostgreSQL | 说明 |
|---|---|---|
| Bool | boolean | |
| Date | date | |
| Date32 | date | |
| DateTime | timestamptz | |
| Decimal | numeric | |
| Float32 | real | |
| Float64 | double precision | |
| IPv4 | inet | |
| IPv6 | inet | |
| Int16 | smallint | |
| Int32 | integer | |
| Int64 | bigint | |
| Int8 | smallint | |
| JSON | jsonb, json | |
| String | text, bytea | |
| UInt16 | integer | |
| UInt32 | bigint | |
| UInt64 | bigint | 值大于 BIGINT 最大值时会报错 |
| UInt8 | smallint | |
| UUID | uuid |
BYTEA
SELECT 查询将输出:
函数与 operator 参考
函数
clickhouse_raw_query
host=localhost port=8123。支持的连接
参数如下:
host:要连接到的主机;必填。port:要连接的 HTTP 端口;默认为8123,除非host是 ClickHouse Cloud 主机,此时默认值为8443dbname:要连接到的数据库名称。username:连接时使用的用户名;默认为defaultpassword:用于身份验证的密码;默认无密码
EXECUTE 权限;请考虑仅向
确实需要执行临时 ClickHouse 查询的角色 GRANT 此权限,
例如专用的 ClickHouse 管理员角色:
适用于不返回记录的查询,但如果查询确实返回值,
则会作为单个文本值返回:
下推函数
pg_clickhouse 会将条件子句 (HAVING 和 WHERE 子句) 中使用的部分 PostgreSQL 内置函数下推到 ClickHouse 中执行。该子集与 ClickHouse 中的对应函数如下:
abs: absfactorial: factorialmod(int2/int4/int8/numeric): 取模pow&power(float8/numeric): powround: roundsin,cos,tan,atan,atan2,sinh,cosh,tanh,asinh,degrees,radians,pi:ClickHouse 数学函数 中的同名函数。asin、acos、atanh、acosh不会下推:对于超出范围的输入,PG 会报错,而 CH 会返回NaN。date_part:date_part('day'): toDayOfMonthdate_part('doy'): toDayOfYeardate_part('dow'): toDayOfWeekdate_part('year'): toYeardate_part('month'): toMonthdate_part('hour'): toHourdate_part('minute'): toMinutedate_part('second'): toSeconddate_part('quarter'): toQuarterdate_part('isoyear'): toISOYeardate_part('week'): toISOYeardate_part('epoch'): toISOYear
date_trunc:date_trunc('week'): toMondaydate_trunc('second'): toStartOfSeconddate_trunc('minute'): toStartOfMinutedate_trunc('hour'): toStartOfHourdate_trunc('day'): toStartOfDaydate_trunc('month'): toStartOfMonthdate_trunc('quarter'): toStartOfQuarterdate_trunc('year'): toStartOfYear
extract(field FROM source):映射与date_part相同date(timestamp)&date(timestamptz): toDate (反解析后为 CH 别名date)array_position:indexOfarray_cat: arrayConcatarray_append: arrayPushBackarray_prepend: arrayPushFrontarray_remove: arrayRemovearray_length&cardinality:lengtharray_to_string: arrayStringConcatstring_to_array: splitByStringsplit_part: splitByString + 数组下标trim_array: arrayResizearray_fill: arrayWithConstantarray_reverse: arrayReversearray_shuffle:arrayShufflearray_sample: arrayRandomSamplearray_sort: arraySort / arrayReverseSortbtrim: trimBothltrim: ltrimrtrim: rtrimconcat_ws: concatWithSeparatorlower(text): lowerUTF8upper(text): upperUTF8substring(text, ...)&substr(text, ...): substringUTF8substring(bytea, ...)&substr(bytea, ...): 子串length(text): lengthUTF8length(bytea)&octet_length:lengthreverse(text): reverseUTF8reverse(bytea): reversestrpos:positionUTF8regexp_like: matchregexp_match: extractGroups 如果正则表达式包含带括号的子表达式;否则为 extractAll 再使用 arraySlice 切片。regexp_replace:replaceRegexpOne 或 replaceRegexpOne,存在g标志时regexp_split_to_array: splitByRegexpmd5: MD5json_extract_path_text:子列语法json_extract_path: toJSONString + 子列语法jsonb_extract_path_text: 子列语法jsonb_extract_path:toJSONString + 子列语法bit_count(bytea): bitCountto_timestamp(float8): fromUnixTimestampto_char(timestamp[tz], fmt): formatDateTime 当fmt为字符串常量,且其中每个关键字在 ClickHouse 中都有完全对应的等价写法时。支持的关键字请参见兼容性说明中的 to_char()。 否则,该函数会在 PostgreSQL 中本地执行。statement_timestamp,transaction_timestamp, &clock_timestamp: nowInBlock64 (nowInBlock64(9, $session_timezone))CURRENT_DATE: now 以及 toDate (toDate(now($session_timezone)))now、CURRENT_TIMESTAMP和LOCALTIMESTAMP: now64 (now64(9, $session_timezone))CURRENT_TIMESTAMP(n)&LOCALTIMESTAMP(n): now64 (now64(n, $session_timezone))CURRENT_DATABASE:作为值由 PostgreSQL 函数传入。CURRENT_SCHEMA:以 PostgreSQL 函数返回值的形式传递。CURRENT_CATALOG:作为值由 PostgreSQL 函数传入。CURRENT_USER:作为值从 PostgreSQL 函数传入。USER:由 PostgreSQL 函数作为值传入。CURRENT_ROLE:作为值从 PostgreSQL 函数中传入。SESSION_USER:作为值从 PostgreSQL 函数传入。
下推操作符
- 数组切片 (
arr[L:U]): arraySlice @>(数组包含) : hasAll<@(数组被包含) : hasAll&&(数组重叠) : hasAny~(正则表达式匹配) : match!~(正则表达式不匹配) : match~*(不区分大小写的正则表达式不匹配) : match!~*(不区分大小写的正则表达式不匹配) : match->>(将 JSON/JSONB 元素提取为文本) : sub-column syntax->(提取 JSON/JSONB) : toJSONString + sub-column syntax
自定义函数
pg_clickhouse 创建的自定义函数,可为部分在 PostgreSQL 中没有对应实现的 ClickHouse 函数提供外部查询下推。如果其中任何函数无法下推,则会引发异常。
扩展下推
re2
re2match→ matchre2extract→ extractre2extractall→ extractAllre2regexpextract→ regexpExtractre2extractgroups→ extractGroupsre2replaceregexpone→ replaceRegexpOnere2replaceregexpall→ replaceRegexpAllre2countmatches→ countMatchesre2countmatchescaseinsensitive→ countMatchesCaseInsensitivere2multimatchany→ multiMatchAnyre2multimatchanyindex→ multiMatchAnyIndexre2multimatchallindices→ multiMatchAllIndices
intarray
idx→ indexOf
fuzzystrmatch
soundex:soundexlevenshtein(2 参数) :editDistanceUTF8
下推类型转换
CAST(x AS bigint) 这类类型转换。
对于不兼容的类型,下推会失败;例如,如果此示例中的 x 是 ClickHouse 的 UInt64,
ClickHouse 会拒绝执行该类型转换。
为了将类型转换下推到不兼容的 数据类型,pg_clickhouse 提供了
以下函数。如果这些函数没有被下推,就会在 PostgreSQL 中引发异常。
聚合函数下推
自定义聚合函数
pg_clickhouse 创建的自定义聚合函数,可为部分在 PostgreSQL
中没有对应函数的 ClickHouse 聚合函数提供外部查询下推。如果这些函数中的任何一个无法下推,
就会引发异常。
下推有序集合聚合函数
ORDER BY expression 作为 argument。例如,以下 PostgreSQL 查询:
ORDER BY 后缀 DESC 和 NULLS FIRST,
使用它们会报错。
percentile_cont(double): quantilequantile(double): quantilequantileExact(double): quantileExact
下推窗口函数
OVER (PARTITION BY ... ORDER BY ...) 子句下推到 ClickHouse;在适用情况下,也包括窗口帧规范。
- row_number
- rank
- dense_rank
- ntile
- cume_dist
- percent_rank
- lead
- lag
- first_value
- last_value
- nth_value
min/max(带OVER子句)
row_number、rank、dense_rank、ntile、cume_dist、
percent_rank) 在下推时会省略窗口帧子句,因为 ClickHouse 不接受这些函数的窗口帧规范。
兼容性说明
正则表达式
-
PostgreSQL 支持 [POSIX 正则表达式],而 ClickHouse 支持
RE2 正则表达式。请注意两者的行为差异:当正则表达式由 ClickHouse 求值时 (例如,在
WHERE子句中) ,请使用 RE2;当它由 Postgres 求值时 (例如,在SELECT子句中) ,请使用 POSIX。 -
pg_clickhouse 通过将 [Postgres 标志] 置于 ClickHouse 正则表达式前面并放入
(?)中,来实现下推。例如:变成 -
两者唯一同时支持、因此可在由 ClickHouse 求值时使用的标志有:
RE2 仅支持这些标志;请勿使用任何其他 [Postgres 标志]。
标志 对应 说明 ii不区分大小写匹配 mm-s^和$除了匹配文本开头/结尾外,也匹配行首/行尾nm-sm的 Postgres 别名p-s不允许 .和[^x]匹配\nss允许 .和[^x]匹配\nt紧凑语法,会被忽略 wm部分换行敏感匹配的反向形式 -
下表概述了各种标志 (以及不加标志的情况,此时
与
s相同) 在匹配换行符和行尾时的影响。请注意,在 Postgres 中,m和p会阻止否定字符类 ([^xyz]) 匹配 换行符,而 ClickHouse 中的对应标志则不会。除此之外, ClickHouse 的行为与 Postgres 相同:应用于 a\nb的模式Postgres ClickHouse 一致? a.btrue true ✔︎ a[^x]btrue true ✔︎ a$false false ✔︎ s标志(?s)a.btrue true ✔︎ (?s)a[^x]btrue true ✔︎ (?s)a$false false ✔︎ m标志(?m)a.bfalse false ✔︎ (?m)a[^x]btrue false ✘ (?m)a$true true ✔︎ p标志(?p)a.bfalse false ✔︎ (?p)a[^x]btrue false ✘ (?p)a$false false ✔︎ w标志(?w)a.btrue true ✔ (?w)a[^x]btrue true ✔ (?w)a$true true ✔ - 传递给正则表达式函数的任何其他标志都会阻止 该函数被下推。
-
例外是
regexp_replace(),它还支持g标志。当 设置g时,pg_clickhouse 会使用replaceRegexpAll()而不是replaceRegexpOne(),并会先移除该标志,再添加其他标志。 -
Postgres 的
regexp_replace()的 replacement 参数支持使用\&来 引用整个匹配;而在 ClickHouse 中,则使用\0表示整个 匹配。该函数下推到 ClickHouse 时,务必使用\0。 -
当没有匹配项时,Postgres
regexp_match会返回NULL,而 它下推执行的表达式则会返回空数组。请使用COALESCE()返回空数组而不是NULL,以便以兼容的方式比较返回值。 例如:
to_char()
timestamp 和 timestamp with time zone 的 to_char()
仅在 format argument 为非 NULL 的 string constant,且其中每个 PostgreSQL 关键字
在 ClickHouse 中都有一个逐字节完全一致的对应项时,才会下推到 ClickHouse formatDateTime。
如果 format 是动态的 (不是 Const) ,或者包含任何不支持的关键字或 modifier,
则该调用会回退到 PostgreSQL 本地求值——绝不会在部分翻译的情况下尝试下推,
因此输出会保持与 PG 兼容。
用于 numeric、interval 及其他非 timestamp 类型的双参数 to_char()
形式永远不会下推;ClickHouse formatDateTime 仅用于格式化日期时间值。
已转换的关键字
| PostgreSQL | ClickHouse | 含义 |
|---|---|---|
YYYY, yyyy | %Y | 4 位年份 |
YY, yy | %y | 2 位年份 |
MM, mm | %m | 补零的月份 (01–12) |
DD, dd | %d | 补零的日期 (01–31) |
DDD, ddd | %j | 补零的一年中的第几天 (001–366) |
HH24, hh24 | %H | 补零的 24 小时制小时 (00–23) |
HH, hh, HH12, hh12 | %I | 补零的 12 小时制小时 (01–12) |
MI, mi | %i | 补零的分钟 (00–59) |
SS, ss | %S | 补零的秒 (00–59) |
Q, q | %Q | 季度 (1–4) |
Mon | %b | 月份简称,例如 Oct |
Dy | %a | 星期简称,例如 Mon |
AM, PM | %p | 上/下午标记,始终为大写 |
带引号的文本和字面量
"..." 包裹的文本会原样传递,其中任何字面的 %
都会写成 %%,以转义 ClickHouse 的格式说明符前缀。引号外的 \"
也会作为字面量 " 原样传递。在 "..." 内部,反斜杠
只会转义 ";其他反斜杠序列都会被视为字面文本。
David E. Wheeler