説明
pg_clickhouse は、foreign data wrapper を含む、ClickHouse データベースに対する リモートクエリ実行を可能にする PostgreSQL 拡張機能です。PostgreSQL 14 以降と ClickHouse 23.3 以降をサポートしています。はじめに
pg_clickhouse を試す最も簡単な方法は Docker image を使うことです。これには、 pg_clickhouse と [re2][re2 extension] 拡張機能を含む標準の PostgreSQL Docker イメージが含まれています:使い方
バージョニングポリシー
pg_clickhouse は、公開リリースにおいて Semantic Versioning に従います。- API の変更時にはメジャーバージョンが増加します
- 後方互換性のある SQL の変更時にはマイナーバージョンが増加します
- binary のみの変更時にはパッチバージョンが増加します
- ライブラリバージョン (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 へのようにパッチバージョンが増加する release では、v0.1 を読み込んでいるすべての
database がその恩恵を受けられ、アップグレードを反映するために
ALTER EXTENSION を実行する必要がないことを意味します。
一方、マイナーバージョンまたはメジャーバージョンが増加する release には
SQL アップグレードスクリプトが付属し、拡張機能を含む既存のすべての database では、
アップグレードを反映するために ALTER EXTENSION pg_clickhouse UPDATE を実行する必要があります。
DDL SQL リファレンス
以下の SQL DDL 文では、pg_clickhouse を使用します。CREATE EXTENSION
CREATE EXTENSION を使用して、データベースに pg_clickhouse を追加します。WITH SCHEMA を使用します (推奨) :
ALTER EXTENSION
pg_clickhouse を変更するには、ALTER EXTENSION を使用します。例:-
pg_clickhouse の新しい release をインストールした後は、
UPDATE句を使用します。 -
拡張機能を新しいスキーマに移動するには、
SET SCHEMAを使用します。
DROP EXTENSION
データベースから pg_clickhouse を削除するには、DROP EXTENSION を使用します。CASCADE 句を使用してください:
CREATE SERVER
ClickHouseサーバーに接続する外部サーバーを作成するには、CREATE SERVER を使用します。例:driver: 使用する ClickHouse 接続ドライバーです。“binary” または “http” のいずれかを指定します。必須です。compression: バイナリドライバー用のネイティブプロトコル圧縮です。“none”、 “lz4”、“zstd” のいずれかです。デフォルトは “lz4” です。“http” ドライバーでは 無視されます。dbname: 接続時に使用する ClickHouse データベースです。デフォルトは “default” です。host: ClickHouse サーバーのホスト名です。デフォルトは “localhost” です。port: 接続先の ClickHouse サーバーのポートです。デフォルトは 次のとおりです。driverが “binary” で、hostが ClickHouse Cloud ホストの場合は 9440driverが “binary” で、hostが ClickHouse Cloud ホストではない場合は 9004driverが “http” で、hostが ClickHouse Cloud ホストの場合は 8443driverが “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 を使用し、それ以外では平文を使用します。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 エンコーディングでは、無効なバイトを Unicode の 置換文字 (�) に置き換えます。その他のエンコーディングではremoveと同じ動作ですtruncate: 最初の無効なバイトの位置でテキストを切り詰めます
ALTER SERVER
ALTER 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 を使用して、ユーザーマッピングの定義を変更できます。DROP USER MAPPING
ユーザーマッピングを削除するには、DROP USER MAPPING を使用します。IMPORT FOREIGN SCHEMA
IMPORT FOREIGN SCHEMA を使用すると、ClickHouse データベースで定義されているすべてのテーブルを、外部テーブルとして PostgreSQL のスキーマにインポートできます。LIMIT TO を使用して、インポート対象を特定のテーブルのみに限定します:
EXCEPT を使用してテーブルを除外します:
-
インポートされたカラムは、
Array内のものも含め、ClickHouse の型の型修飾子を 保持します。たとえば、Array(Decimal(12,6))はnumeric(12,6)[]としてインポートされます。 -
NullableカラムはNOT NULLなしでインポートされます。ただし、Array内のNullableはこの限りではありません。PostgreSQL の配列は常に NULL 要素を許容するためです。 -
AggregateFunctionおよびSimpleAggregateFunctionカラムは、ClickHouse での宣言にかかわらずNOT NULLなしでインポートされます。詳しくは State Columns andNOT NULLを参照してください。 -
Tupleカラムはtext[]としてインポートされます。Mapカラム、およびflatten_nested=0で作成されたNestedカラムはtext[][]としてインポートされます。いずれの変換でもNOTICEが出力されます。PostgreSQL のrecord疑似型ではテーブルのカラムを定義できないため、 各タプルは値の配列に、各マップはキー・バリューのペアの 2 次元配列に、各 Nested 値は行の 2 次元配列になります。フィールドをレコードとして読み取るには、カラムを 対応する複合型の配列に変更してください。例については Manual Type Mappings を参照してください。 -
精度が 6 (マイクロ秒) を超える
DateTime64およびTime64カラムでもNOTICEが出力されます。PostgreSQL では精度の上限がtimestamp(6)およびtime(6)であるためです。 -
ClickHouse の
JSONより前から存在するレガシーなObject('json')型をはじめ、 PostgreSQL に対応する型が存在しないカラム型はエラーになります。
CREATE FOREIGN TABLE
ClickHouseデータベースのデータをクエリできる外部テーブルを作成するには、CREATE FOREIGN TABLE を使用します。database: リモートデータベースの名前です。デフォルトでは、外部サーバーに 定義されているデータベースが使用されます。table_name: リモートテーブルの名前です。デフォルトでは、外部テーブルに 指定された名前が使用されます。engine: ClickHouse テーブルで使用される [テーブルエンジン] です。CollapsingMergeTree()およびAggregatingMergeTree()では、pg_clickhouse が テーブル上で実行される関数式に対して自動的にパラメーターを適用します。
-
column_name: ClickHouse 側のカラム名です。クエリや INSERT のデパース時には、PostgreSQL の属性名よりもこちらが優先して使用されます。 これは、引用符なしの小文字の PostgreSQL カラム名を 大文字と小文字を区別する ClickHouse カラムにマッピングする場合に便利です。例: -
AggregateFunction: [AggregateFunction 型] カラムに適用される 集約関数の名前です。データ型を、その関数に渡される ClickHouse の型にマッピングし、適切なカラムオプションで 集約関数名を指定すると、pg_clickhouse が自動的に カラムを評価する集約関数にMergeを付加します。State Columns andNOT NULLで説明されている問題を避けるため、カラムは Nullable として宣言してください。 -
SimpleAggregateFunction: [SimpleAggregateFunction 型] カラムに適用される 集約関数の名前です。データ型を、その関数に渡される ClickHouse の型にマッピングし、適切なカラムオプションで 集約関数名を指定してください。
State Columnsと NOT NULL
AggregateFunction および SimpleAggregateFunction のカラムは Nullable のままにしてください。
PostgreSQL 19 では、NOT NULL のステート
カラムに対する count(column) が count(*) に置き換えられるため、ステートがマージされず、行数がカウントされてしまいます。
例として、ユーザーごとに 1 つの count ステートを保持し、各ステートが 1,000 件のイベントから
構築されている ClickHouse テーブルを考えます。
NOT NULL を指定すると、PostgreSQL はステートの数をカウントしてしまうため、正しくないカウント結果になります。
NOT NULL を指定しない場合、pg_clickhouse は countMerge() を使用してステートをマージするため、
正しいカウント 1000 が得られます:
ALTER FOREIGN TABLE を使用します。
NOT NULL は PostgreSQL にのみ影響します。そのため、IMPORT FOREIGN
SCHEMA では、ステート カラムは Nullable としてインポートされます。
ALTER FOREIGN TABLE
外部テーブルの定義を変更するには、ALTER FOREIGN TABLE を使用します。DROP FOREIGN TABLE
外部テーブルを削除するには、DROP FOREIGN TABLEを使用します。CASCADE 句を使用します:
DML SQL リファレンス
以下の SQL DML 式では、pg_clickhouse を使用することがあります。例は、 以下の ClickHouse テーブルを前提としています:EXPLAIN
EXPLAIN コマンドは想定どおりに動作しますが、VERBOSE オプションを指定すると
ClickHouse の “Remote SQL” クエリが出力されます:
SELECT
SELECTステートメントを使うと、他のテーブルと同様に pg_clickhouse テーブルに対してクエリを実行できます。nodes テーブルのローカルコピーを作成し、リモートテーブルの代わりに
それと JOIN します。
node_id でグループ化することで、
集約処理のより多くを ClickHouse 側に任せられ、その後で
ルックアップテーブルと join できます。
node_id ごとの集約がプッシュダウンされるようになり、
Postgres に引き戻す必要のある行数が 1000 行 (全件) から
各ノード 1 行ずつのわずか 8 行まで削減されます。
パーティション化テーブル
PostgreSQL の[パーティション化テーブル]では、ローカルパーティションと ClickHouse をバックエンドとする外部パーティションを混在させることができます。一般的な構成では、古いデータを ClickHouse にオフロードし、最新のデータは 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, sum of squared deviations}の状態を配列としてプッシュダウンします。
FILTER (WHERE …) も、これらの集約関数とともにプッシュダウンされます。
フォールバックする場合
遷移状態が PostgreSQL の不透明なinternal 型である集約関数には、
ポータブルな表現がないため、外部パーティションは行を取得してローカルで集約します。
これには numeric に対するすべての集約関数のほか、avg(bigint) と avg(interval) が含まれます。
DISTINCT、順序付き集合集約関数、可変長引数集約関数もフォールバックします。
PREPARE, EXECUTE, DEALLOCATE
v0.1.2以降、pg_clickhouse は主に PREPARE コマンドで作成される パラメータ付きクエリをサポートしています:{param:type} 形式の[クエリパラメータ]が送信されます。
INSERT
リモートのClickHouseテーブルに値を挿入するには、INSERT コマンドを使用します。COPY
リモートの ClickHouse テーブルに複数の行をまとめて挿入するには、COPY コマンドを使用します。⚠️ Batch API の制限 pg_clickhouse は、PostgreSQL FDW のバッチ insert API のサポートをまだ実装していません。そのため、現在 COPY はレコードを 挿入するために INSERT ステートメントを使用しています。これは今後のリリースで改善される予定です。
LOAD
pg_clickhouse 共有ライブラリを読み込むには、LOAD を使用します:SET
SET を使用して、pg_clickhouse のカスタム設定パラメーターを設定します。pg_clickhouse.session_settings
pg_clickhouse.session_settings パラメーターは、後続のクエリに適用する [ClickHouse
設定] を指定します。例:
join_use_nulls、IN ファミリーには transform_null_in
(IN と NULL のセマンティクスを参照) 。
date_time_output_format: http ドライバーではこれが “iso” である必要がありますformat_tsv_null_representation: http ドライバーではデフォルト値が必要ですoutput_format_tsv_crlf_end_of_linehttp ドライバーではデフォルト値が必要です
pg_clickhouse.session_settings を設定する前に、
pg_clickhouse を読み込んでおく必要がある点に注意してください。共有ライブラリのプリロード を使用するか、
または拡張機能内のいずれかのオブジェクトを使って、確実に読み込まれるようにしてください。
pg_clickhouse.pushdown_regex
pg_clickhouse.pushdown_regex パラメータは、pg_clickhouse が
正規表現関数および演算子をプッシュダウンするかどうかを制御します。既定では
プッシュダウンが有効です。プッシュダウンを無効にするには、このパラメータを false に設定します:
ALTER ROLE
ALTER ROLE’sSET コマンドを使用すると、pg_clickhouse をプリロードしたり、
特定のロールに対してそのパラメータをSETしたりできます。
RESET コマンドを使用して、pg_clickhouse のプリロード設定
やパラメータをリセットします:
プリロード
すべて、またはほぼすべてのPostgres接続で pg_clickhouse を使用する必要がある場合は、 これを自動的に読み込むために、共有ライブラリのプリロードの使用を検討してください:session_preload_libraries
PostgreSQL への新しい接続のたびに共有ライブラリを読み込みます:
shared_preload_libraries
起動時に、共有ライブラリを PostgreSQL の親プロセスに読み込みます:
データ型
この表は、ClickHouse のデータ型と PostgreSQL のデータ型の推奨対応関係を示しています。 IMPORT FOREIGN SCHEMA はこの対応関係に基づいて、 適切な型修飾子と配列の次元を導出します。別の PostgreSQL 型を宣言する場合は、CREATE FOREIGN TABLE を使用してください。 「追加の読み取り先」列には、PostgreSQL の明示的なキャストに加えてbinary ドライバーがサポートする変換を記載しています。
セルが空の場合でも、これらのキャストは使用できます。値は変換先の型に
収まる必要があります。これらの変換先は読み取り時のものであり、書き込みには別の
変換ルールが適用されます。
どのカラムも、
text、varchar、またはその他の文字列型として読み取ることもできます。値は
まず上記の PostgreSQL 型となり、その後、その型の出力関数を通じて
レンダリングされます。テキスト型として読み取られた ClickHouse の文字列は
データベースのエンコーディングに照らして検証されるため、PostgreSQL が読み取れないバイトが含まれているとエラーになります。
String、FixedString、Enum、または JSON のカラムを BYTEA として宣言すると、
ClickHouse が書き込んだとおりのバイト列として読み取れます。
入力互換の型は、PostgreSQL の入力関数を使用して文字列を読み取ることができます。
複合型では、フィールドが一致し、かつその順序も一致している必要があります。タプルを
配列として読み取るには、各フィールドが配列の要素型に変換可能である必要があり、
配列であるフィールドを含めることはできません。
配列として読み取る場合、Map はキー・バリューのペアごとに 1 行、Nested は
ネストされたレコードごとに 1 行となります。タプルを box として読み取るには 2 つの点を、
circle として読み取るには点と半径を、line として読み取るには 3 つの係数を指定します。
追加の注記と詳細を以下に示します。
型変換
binary ドライバーでは、代替のスカラー型には可能な場合 PostgreSQL の明示的な
キャストが使用され、配列要素は宣言された
要素型に変換されます。サポートされていない変換や範囲外の値はエラーになります。
どちらのドライバーでも、ClickHouse の Interval 型を smallint、integer、
または bigint にマッピングすると、単位数として読み書きできます。例えば、
IntervalDay の値 3 は整数 3 にマッピングされます。
IntervalNanosecond を bigint にマッピングするとナノ秒の精度が保持されますが、
interval にマッピングするとマイクロ秒単位に切り捨てられます。
BYTEA
ClickHouse は PostgreSQL の BYTEA 型に相当する型を提供していませんが、[String] 型に任意のバイト列を格納できます。通常、ClickHouse の文字列は PostgreSQL の [TEXT] にマッピングしますが、バイナリデータを扱う場合は BYTEA にマッピングしてください。例:SELECTクエリの出力は以下のとおりです:
FixedString(N) カラムは、短い値を NUL バイトでパディングします。テキストカラムでは
この末尾のパディングが削除されますが、BYTEA カラムではすべてのバイトが保持されます。
複合型
Array
ClickHouse の [Array] は PostgreSQL の配列に直接対応し、セマンティクスも同等です。主な違いは、Postgres の多次元配列では、配列式の次元がすべて一致していなければならない点です。[[1], [2,3]] のように次元が異なる
ClickHouse の配列を読み取ろうとすると、エラーが発生します。
配列のインデックスアクセスは、多次元のインデックスアクセスも含め、必要に応じてプッシュダウンされます。例:
Map
PostgreSQL には、ClickHouse の [Map] 型に対応する型がありません。 そのため pg_clickhouse は [Map] カラムをtext[][] にマッピングし、各キー・バリュー
ペアをそれぞれ個別の配列として表現します。IMPORT FOREIGN SCHEMA でも
このマッピングが使用されます。また、Map 値を配列として INSERT することもできます。例:
Map を挿入するには binary ドライバーが必要です。このドライバーは ClickHouse サーバーからカラム型を取得します。一方、http ドライバーはカラム型を取得しないため、適切な値をフォーマットして挿入するために必要な情報を持ちません。Tuple
同様に、ClickHouse の [Tuple] カラムはtext[] にマッピングされ、バイナリドライバー経由での INSERT に対応しています。IMPORT FOREIGN SCHEMA は、このようなマッピングを行う際に NOTICE を出力します。
Nested
デフォルトでは、ClickHouse はNested カラムをフィールドごとに 1 つの Array カラムへ分割します
(flatten_nested=1)。IMPORT FOREIGN SCHEMA は、これらのカラムを
ClickHouse の system.columns カタログから読み取り、それぞれ個別の PostgreSQL 配列
カラムとして作成します。その際、items.a や items.b のようなドット区切りの名前はそのまま保持されます。たとえば、
次の外部テーブルがあるとします。
WHERE 句で値をフィルタすることもできます。
flatten_nested=0 で作成された [Nested] カラムは、ネストされた行ごとに 1 つの要素を持つ配列にマッピングされます。各配列要素には、対応する行の値が格納されます。
c2 Nested(id Int64, name String) の場合は、次のようになります。
text[][] カラムのプッシュダウンは失敗します。
手動による型マッピング
IMPORT FOREIGN SCHEMA は汎用的な PostgreSQL 型を使用します。たとえば、
[Enum]、[Tuple]、Map、およびフラット化されていない
[Nested] (flatten_nested = 0) の各カラムを持つ、次のような ClickHouse テーブルがあるとします。
key と value) になります。
Nested と Map は複合型の配列になり、Tuple は 1 つの複合型の値になります。
SELECT
リストの中で使用することもできます:
WHERE 句内の [Nested] 型についても、フィールド名が
同一であれば同様に動作します:
INSERT は、現時点ではサポートされていません。
関数と演算子のリファレンス
関数
これらの関数は、ClickHouse データベースにクエリを実行するためのインターフェイスです。clickhouse_server_version
major.minor.patch形式で返します。必要に応じて、server’s optionsおよびcurrent user’s user mappingを使用して接続します。
SELECT version() クエリからバージョンを取得し、接続の存続期間中キャッシュします。
clickhouse_query
driver、
credentials、database、およびconnection cacheが再利用されます。
最初のargumentには、CREATE SERVERで作成したserverの名前を指定します。
カラム定義リスト (AS name(col type, ...)) が必要です。PostgreSQLでは行を取得する前に
結果のshapeを把握する必要があり、クエリが返すカラムと一致している必要があります。値は、
外部テーブルのカラムと同様に、ClickHouseから宣言された型に変換されます。DDLなど、
結果を返さないステートメントでは宣言するものがありません。そのようなステートメントは
代わりにclickhouse_performで実行してください。
デフォルトでは、どのロールにもEXECUTEアクセス権はありません。関数の使用を許可するには、
ロールにGRANTしてください。
clickhouse_perform
clickhouse_query で
結果の shape を宣言できないステートメントに使用します。server は
clickhouse_query と同じ方法で解決され、その
driver、credentials、database、および connection cache が再利用されます。
プロシージャとして、SELECT ではなく CALL で呼び出す必要があり、行は返しません。
デフォルトでは、どのロールにも EXECUTE アクセス権は付与されていません。プロシージャの使用を許可するには、ロールに GRANT します。
プッシュダウン関数
pg_clickhouse は、条件式 (HAVING 句および WHERE 句) で使用される PostgreSQL の組み込み関数の一部をプッシュダウンします。対応する関数は、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 aliasdateとしてデパースされます)array_position: indexOf に nullIf を使用して0をNULLに変換し、検索開始インデックスを指定する第 3 引数がある場合は arraySlice を使用します。なお、現在nanは一致しませんarray_cat: arrayConcatarray_append: arrayPushBackarray_prepend: arrayPushFrontarray_remove: arrayRemovecardinality: ClickHouse 26.9 以降では arrayFlattenedLength、 それ以前のバージョンでは length (外側の配列の要素のみをカウントします)array_length(array, 1):nullIf(length(array), 0)array_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: trimLeftrtrim: trimRightconcat_ws: concatWithSeparatorlower(text): lowerUTF8upper(text): upperUTF8substring(text, ...)&substr(text, ...): substringUTF8substring(bytea, ...)&substr(bytea, ...): substringlength(text): lengthUTF8length(bytea)&octet_length: lengthreverse(text): reverseUTF8reverse(bytea): reversestrpos: positionUTF8regexp_like: matchregexp_match: 正規表現に丸括弧で囲まれた部分式が含まれている場合は extractGroups、 そうでない場合は extractAll を arraySlice でスライスしたものです。regexp_replace:gフラグがある場合は replaceRegexpOne、または replaceRegexpOneregexp_split_to_array: splitByRegexpmd5: MD5sha224、sha256、sha384、sha512: 対応する ClickHouse の SHA 関数fmtが文字列定数 (大文字と小文字を区別しない) の場合のencode(bytea, fmt):encode(bytea, 'hex'): hex を lower でラップします。 PostgreSQL は小文字の hex を出力するためです。encode(bytea, 'base64'): base64Encode を replaceRegexpAll でラップし、 PostgreSQL の MIME (RFC 2045) 形式の 76 文字ごとの改行を再現します。encode(bytea, 'base64url')(PostgreSQL 19 以降) : base64URLEncode。 これは、padding なしの PostgreSQL の RFC 4648 URL アルファベットに一致します。
json_extract_path_text: サブカラムの構文json_extract_path: toJSONString + サブカラムの構文jsonb_extract_path_text: サブカラム構文jsonb_extract_path: toJSONString + サブカラムの構文bit_count(bytea): bitCountto_timestamp(float8): toDateTime64to_char(timestamp[tz], fmt):fmtが、含まれるすべてのキーワードに ClickHouse で忠実に対応するものがある文字列定数である場合は、formatDateTime です。対応しているキーワードについては、Compatibility Notes の 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 関数から値として渡されるものです。
プッシュダウン演算子
- Array スライス (
arr[L:U]): arraySlice @>(配列が含む) : hasAll<@(配列に含まれる) : hasAll&&(配列の重複) : hasAny~(正規表現に一致) : match!~(正規表現に一致しない) : match~*(大文字と小文字を区別しない正規表現に一致しない) : match!~*(大文字と小文字を区別しない正規表現に一致しない) : match->>(JSON/JSONB の要素をテキストとして抽出) : sub-column syntax->(JSON/JSONB を抽出) : toJSONString + sub-column syntax
IN と NULL のセマンティクス
ClickHouse はIN を二値論理で評価します。プローブで一致が見つからない場合、NULL が含まれていても 0 を返しますが、PostgreSQL では NULL になります。PostgreSQL のセマンティクスを維持するため、pg_clickhouse は定数リストまたは配列に対する IN ファミリー (IN、NOT IN、= ANY、= ALL、<> ANY、<> ALL) を無条件にプッシュダウンします。プローブと配列要素のいずれも NULL になり得ないことを証明できる場合はネイティブ形式または低コストな形式を使用し、それ以外の場合は実行時に NULL 値を確認するガード付き CASE 形式を使用します。これにより、SELECT リストや GROUP BY などの値の位置を含むあらゆるコンテキストで、PostgreSQL と完全に同じ三値の結果 (TRUE、FALSE、NULL) を計算します。
NULL 許容カラムに対する NOT IN (SELECT ...) フィルタもプッシュダウンされ、PostgreSQL の動作を維持するための補償ガードを付加して逆変換されます。NULL を含む集合はすべての行を除外し、NULL のプローブが通過するのは集合が空の場合のみです。NOT NULL 宣言によって不要であることが証明できる場合は、各ガードを省略します。上記の配列形式とは異なり、このガードは通常のフィルタ条件内 (または NOT 配下) でのみ適用されます。値の位置にある IN (SELECT ...) や、グループ化または集計されたサブクエリ本体は、引き続きプッシュダウンされません。カラムを NOT NULL と宣言すると、より低コストなガードなし形式を送信できるため、プッシュダウンを最大化できます。IMPORT FOREIGN SCHEMA は、Nullable ではない ClickHouse カラムに対してこれを自動的に行います。この証明では、非 NULL 定数、NOT NULL カラム、およびそれらに対する基本的な算術演算 (+、-、*、単項 -) を追跡します。
これらの規則は、ClickHouse のデフォルト設定である transform_null_in = 0 を前提としています。pg_clickhouse は pg_clickhouse.session_settings パラメータのデフォルト値を通じて、すべてのクエリでこれを設定します。これにより、ClickHouseサーバープロファイルがこの設定を暗黙的に変更することはありません。transform_null_in = 1 を設定すると、プッシュダウンされたすべての IN のセマンティクスが破綻します。
カスタム関数
pg_clickhouse が作成するこれらのカスタム関数は、PostgreSQL に対応する機能がない一部の ClickHouse 関数について、外部クエリのプッシュダウンを可能にします。これらの関数のいずれかをプッシュダウンできない場合は、例外が発生します。拡張機能のプッシュダウン
pg_clickhouse は、一部のコア拡張機能やサードパーティ拡張機能の関数を認識し、それらを ClickHouse の対応する関数にプッシュダウンします。re2
すべての [re2 拡張機能] 演算子および関数は、ClickHouse に 1:1 でプッシュダウンされます。@~→ matchre2match→ matchre2extract→ extractre2extractall→ extractAllre2regexpextract→ regexpExtractre2extractgroups→ extractGroupsre2replaceregexpone→ replaceRegexpOnere2replaceregexpall→ replaceRegexpAllre2countmatches→ countMatchesre2countmatchescaseinsensitive→ countMatchesCaseInsensitivere2multimatchany→ multiMatchAnyre2multimatchanyindex→ multiMatchAnyIndexre2multimatchallindices→ multiMatchAllIndices
intarray
[intarray] 関数のうち、ClickHouse にプッシュダウンされるものは 1 つあります。idx→ indexOf
fuzzystrmatch
2つの [fuzzystrmatch] 関数が ClickHouse にプッシュダウンされます。soundex: soundexlevenshtein(2引数) : editDistanceUTF8
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 にプッシュダウンされます。- any_value
- array_agg
- avg
- bit_and
- bit_or
- bit_xor
- bool_and / every
- bool_or
- count
- corr
- covarpop
- covarsamp
- min
- max
- stddev_pop
- stddev_samp / stddev
- string_agg
- sum
- var_op
- var_samp /variance
カスタム集約関数
pg_clickhouse が作成するこれらのカスタム集約関数は、PostgreSQL に同等の機能がない一部の ClickHouse 集約関数について、外部クエリのプッシュダウンを提供します。これらの関数のいずれかをプッシュダウンできない場合は、例外をスローします。ordered-set 集約関数 の プッシュダウン
これらのordered-set 集約関数は、それぞれの direct argument をパラメータとして、ORDER BY 式を引数として渡すことで、ClickHouse のparametric
集約関数に対応します。たとえば、次の PostgreSQL クエリです。
ORDER BY 接尾辞である DESC と NULLS FIRST は
サポートされておらず、error が発生します。
percentile_cont(double): quantilepercentile_cont(double[]): quantilespercentile_disc(double): quantileExactLowpercentile_disc(double[]): quantilesExactLow
カスタム ordered-set 集約関数
pg_clickhouse によって作成されたこれらのカスタムordered-set 集約関数は、一部の ClickHouse parametric 集約関数に対する 外部クエリのプッシュダウン を提供します。これらの関数のいずれかをプッシュダウンできない場合は、 例外 が発生します。quantile(double): quantilequantileExact(double): quantileExact
カスタム ordered-set 集約関数
pg_clickhouse が提供するこれらのカスタムordered-set 集約関数では、特定の ClickHouse parametric 集約関数に対して外部クエリのプッシュダウンが可能です。これらの関数のいずれかをプッシュダウンできない場合は、例外が発生します。プッシュダウンされるウィンドウ関数
以下の PostgreSQL [ウィンドウ関数]は、該当する場合はフレーム指定を含む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 がこれらの関数のフレーム指定を受け付けないため、プッシュダウン時にフレーム句が省略されます。
互換性に関する注意
正規表現
pg_clickhouse.pushdown_regex が true の場合 (デフォルト) 、pg_clickhouse は 正規表現を ClickHouse の同等表現に プッシュダウン し、基本的な互換性を確保するよう努めます。 ただし、両者の違いと、それらを pg_clickhouse がどのように扱うかは把握しておいてください。-
PostgreSQL は [POSIX 正規表現] をサポートし、ClickHouse は
[RE2 正規表現][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を返しますが、 push down される式は空の配列を返します。戻り値を 互換性のある形で比較するには、COALESCE()を使ってNULLではなく空の配列を返すようにします。例えば:
to_char()
timestamp および timestamp with time zone に対する PostgreSQL の [to_char()] は、フォーマット引数が非 NULL の文字列定数であり、なおかつ含まれる PostgreSQL のキーワードがすべて ClickHouse にバイト単位で完全一致する対応を持つ場合にのみ、ClickHouse の [formatDateTime] にプッシュダウンされます。フォーマットが動的な場合、または未サポートのキーワードや modifier を含む場合、この呼び出しは PostgreSQL でローカルに評価されます。pg_clickhouse が部分的な変換をプッシュダウンすることはないため、出力の互換性は保たれます。
numeric、interval、およびその他の timestamp 以外の型に対する 2 引数の to_char() 形式は、プッシュダウンされません。ClickHouse の [formatDateTime] は日付時刻値のみをフォーマットします。
変換されるキーワード
引用符付きテキストとリテラル
"..." で囲まれたテキストは、そのまま渡されます。リテラルの % は、
ClickHouse の指定子プレフィックスをエスケープするため、%% に
二重化されます。引用符の外側にある \" も、リテラルの " としてそのまま
渡されます。"..." の内側では、バックスラッシュでエスケープされるのは " のみで、
それ以外のバックスラッシュシーケンスはリテラルテキストとして扱われます。
著者
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_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”