pg_clickhouse Reference Documentation
Description
pg_clickhouse is a PostgreSQL extension that enables remote query execution on ClickHouse databases, including a foreign data wrapper. It supports PostgreSQL 13 and higher and ClickHouse 23 and higher.
Getting Started
The simplest way to try pg_clickhouse is the Docker image, which contains the standard PostgreSQL Docker image with the pg_clickhouse extension:
See the tutorial to get started importing ClickHouse tables and pushing down queries.
Usage
Versioning Policy
pg_clickhouse adheres to Semantic Versioning for its public releases.
- The major version increments for API changes
- The minor version increments for backward compatible SQL changes
- The patch version increments for binary-only changes
Once installed, PostgreSQL tracks two variations of the version:
- The library version (defined by
PG_MODULE_MAGICon PostgreSQL 18 and higher) includes the full semantic version, visible in the output of thepg_get_loaded_modules()function. - The extension version (defined in the control file) includes only the
major and minor versions, visible in the
pg_catalog.pg_extensiontable, the output of thepg_available_extension_versions()function, and\dx pg_clickhouse.
In practice this means that a release that increments the patch version, e.g.
from v0.1.0 to v0.1.1, benefits all databases that have loaded v0.1 and
do not need to run ALTER EXTENSION to benefit from the upgrade.
A release that increments the minor or major versions, on the other hand, will
be accompanied by SQL upgrade scripts, and all existing database that contain
the extension must run ALTER EXTENSION pg_clickhouse UPDATE to benefit from
the upgrade.
DDL SQL Reference
The following SQL DDL expressions use pg_clickhouse.
CREATE EXTENSION
Use CREATE EXTENSION to add pg_clickhouse to a database:
Use WITH SCHEMA to install it into a specific schema (recommended):
ALTER EXTENSION
Use ALTER EXTENSION to change pg_clickhouse. Examples:
-
After installing a new release of pg_clickhouse, use the
UPDATEclause: -
Use
SET SCHEMAto move the extension to a new schema:
DROP EXTENSION
Use DROP EXTENSION to remove pg_clickhouse from a database:
This command fails if there are any objects that depend on pg_clickhouse. Use
the CASCADE clause to drop them, too:
CREATE SERVER
Use CREATE SERVER to create a foreign server that connects to a ClickHouse server. Example:
The supported options are:
driver: The ClickHouse connection driver to use, either "binary" or "http". Required.dbname: The ClickHouse database to use upon connecting. Defaults to "default".host: The host name of the ClickHouse server. Defaults to "localhost";port: The port to connect to on the ClickHouse server. Defaults as follows:- 9440 if
driveris "binary" andhostis a ClickHouse Cloud host - 9004 if
driveris "binary" andhostis not a ClickHouse Cloud host - 8443 if
driveris "http" andhostis a ClickHouse Cloud host - 8123 if
driveris "http" andhostis not a ClickHouse Cloud host
- 9440 if
ALTER SERVER
Use ALTER SERVER to change a foreign server. Example:
The options are the same as for CREATE SERVER.
DROP SERVER
Use DROP SERVER to remove a foreign server:
This command fails if any other objects depend on the server. Use CASCADE to
also drop those dependencies:
CREATE USER MAPPING
Use CREATE USER MAPPING to map a PostgreSQL user to a ClickHouse user. For
example, to map the current PostgreSQL user to the remote ClickHouse user when
connecting with the taxi_srv foreign server:
The The supported options are:
user: The name of the ClickHouse user. Defaults to "default".password: The password of the ClickHouse user.
ALTER USER MAPPING
Use ALTER USER MAPPING to change the definition of a user mapping:
The options are the same as for CREATE USER MAPPING.
DROP USER MAPPING
Use DROP USER MAPPING to remove a user mapping:
IMPORT FOREIGN SCHEMA
Use IMPORT FOREIGN SCHEMA to import all the tables defines in a ClickHouse database as foreign tables into a PostgreSQL schema:
Use LIMIT TO to limit the import to specific tables:
Use EXCEPT to exclude tables:
pg_clickhouse will fetch a list of all the tables in the specified ClickHouse database ("demo" in the above examples), fetch column definitions for each, and execute CREATE FOREIGN TABLE commands to create the foreign tables. Columns will be defined using the supported data types and, were detectible, the options supported by CREATE FOREIGN TABLE.
IMPORT FOREIGN SCHEMA runs quote_identifier() on the table and column
names it imports, which double-quotes identifiers with uppercase characters
or blank spaces. Such table and column names thus must be double-quoted in
PostgreSQL queries. Names with all lowercase and no blank space characters
do not need to be quoted.
For example, given this ClickHouse table:
IMPORT FOREIGN SCHEMA creates this foreign table:
Queries therefore must quote appropriately, e.g.,
To create objects with different names or all lowercase (and therefore case-insensitive) names, use CREATE FOREIGN TABLE.
CREATE FOREIGN TABLE
Use CREATE FOREIGN TABLE to create a foreign table that can query data from a ClickHouse database:
The supported table options are:
database: The name of the remote database. Defaults to the database defined for the foreign server.table_name: The name of the remote table. Default to the name specified for the foreign table.engine: The table engine used by the ClickHouse table. ForCollapsingMergeTree()andAggregatingMergeTree(), pg_clickhouse automatically applies the parameters to function expressions executed on the table.
Use the data type appropriate for the remote ClickHouse data type of each column. For AggregateFunction Type and SimpleAggregateFunction Type columns, map the data type to the ClickHouse type passed to the function and specify the name of the aggregate function via the appropriate column option:
AggregateFunction: The name of the aggregate function applied to an AggregateFunction Type columnSimpleAggregateFunction: The name of the aggregate function applied to an SimpleAggregateFunction Type column
Example:
(aggregatefunction 'sum')
For columns with the AggregateFunction function, pg_clickhouse will
automatically append Merge to an aggregate function evaluating the column.
ALTER FOREIGN TABLE
Use ALTER FOREIGN TABLE to change the definition of a foreign table:
The supported table and column options are the same as for CREATE FOREIGN TABLE.
DROP FOREIGN TABLE
Use DROP FOREIGN TABLE to remove a foreign table:
This command fails if there are any objects that depend on the foreign table.
Use the CASCADE clause to drop them, too:
DML SQL Reference
The SQL DML expressions below may use pg_clickhouse. Examples depend on these ClickHouse tables, created by make-logs.sql:
EXPLAIN
The EXPLAIN command works as expected, but the VERBOSE option triggers the
ClickHouse "Remote SQL" query to be emitted:
This query pushes down to ClickHouse via a "Foreign Scan" plan node, the remote SQL.
SELECT
Use the SELECT statement to execute queries on pg_clickhouse tables just like any other tables:
pg_clickhouse works to push query execution down to ClickHouse as much as possible, including aggregate functions. Use EXPLAIN to determine the pushdown extent. For the above query, for example, all execution is pushed down to ClickHouse
pg_clickhouse also pushes down JOINs to tables that are from the same remote server:
Joining with a local table will generate less efficient queries without
careful tuning. In this example, we make a local copy of the
nodes table and join to it instead of the remote table:
In this case, we can push more of the aggregation down to ClickHouse by
grouping on node_id instead of the local column, and then join
to the lookup table later:
The "Foreign Scan" node now pushes down aggregation by node_id, reducing
the number of rows that must be pulled back into Postgres from 1000 (all of
them) to just 8, one for each node.
PREPARE, EXECUTE, DEALLOCATE
As of v0.1.2, pg_clickhouse supports parameterized queries, mainly created by the PREPARE command:
Use EXECUTE as usual to execute a prepared statement:
pg_clickhouse pushes down the aggregations, as usual, as seen in the EXPLAIN verbose output:
Note that it has sent the full date values, not the parameter placeholders.
This holds for the first five requests, as described in the PostgreSQL
[PREPARE notes]. On the sixth execution, it sends ClickHouse
{param:type}-style [query parameters]:
parameters:
Use DEALLOCATE to deallocate a prepared statement:
INSERT
Use the INSERT command to insert values into a remote ClickHouse table:
COPY
Use the COPY command to insert a batch of rows into a remote ClickHouse table:
⚠️ Batch API Limitations
pg_clickhouse has not yet implemented support for the PostgreSQL FDW batch insert API. Thus COPY currently uses INSERT statements to insert records. This will be improved in a future release.
LOAD
Use LOAD to load the pg_clickhouse shared library:
It's not normally necessary to use LOAD, as Postgres will automatically load pg_clickhouse the first time any of of its features (functions, foreign tables, etc.) are used.
The one time it may be useful to LOAD pg_clickhouse is to SET pg_clickhouse parameters before executing queries that depend on them.
SET
Use SET to set the the pg_clickhouse.session_settings runtime parameter.
This parameter configures ClickHouse settings to be set on subsequent
queries. Example:
The default is join_use_nulls 1. Set it to an empty string to fall back on
the ClickHouse server's settings.
The syntax is a comma-delimited list of key/value pairs separated by one or more spaces. Keys must correspond to ClickHouse settings. Escape spaces, commas, and backslashes in values with a backslash:
Or use single quoted values to avoid escaping spaces and commas; consider using dollar quoting to avoid the need to double-quote:
If you care about legibility and need to set many settings, use multiple lines, for example:
pg_clickhouse does not validate the settings, but passes them on to ClickHouse for every query. It thus supports all settings for each ClickHouse version.
Note that pg_clickhouse must be loaded before setting
pg_clickhouse.session_settings; either use [shared library preloading] or
simply use one of the objects in the extension to ensure it loads.
ALTER ROLE
Use ALTER ROLE's SET command to preload pg_clickhouse
and/or SET its parameters for specific roles:
Use the ALTER ROLE's RESET command to reset pg_clickhouse preloading
and/or parameters:
Preloading
If every or nearly every Postgres connection needs to use pg_clickhouse, consider using [shared library preloading] to automatically load it:
session_preload_libraries
Loads the shared library for every new connection to PostgreSQL:
Useful to take advantage of updates without restarting the server: just reconnect. May also be set for specific users or roles via ALTER ROLE.
shared_preload_libraries
Loads the shared library into the PostgreSQL parent process at startup time:
Useful to save memory and load overhead for every session, but requires the cluster to be restart when the library is updated.
Function and Operator Reference
Data Types
pg_clickhouse maps the following ClickHouse data types to PostgreSQL data types:
| ClickHouse | PostgreSQL | Notes |
|---|---|---|
| Bool | boolean | |
| Date | date | |
| Date32 | date | |
| DateTime | timestamp | |
| Decimal | numeric | |
| Float32 | real | |
| Float64 | double precision | |
| IPv4 | inet | |
| IPv6 | inet | |
| Int16 | smallint | |
| Int32 | integer | |
| Int64 | bigint | |
| Int8 | smallint | |
| JSON | jsonb | HTTP engine only |
| String | text | |
| UInt16 | integer | |
| UInt32 | bigint | |
| UInt64 | bigint | Errors on values > BIGINT max |
| UInt8 | smallint | |
| UUID | uuid |
Functions
These functions provide the interface to query a ClickHouse database.
clickhouse_raw_query
Connect to a ClickHouse service via its HTTP interface, execute a single
query, and disconnect. The optional second argument specifies a connection
string that defaults to host=localhost port=8123. The supported connection
parameters are:
host: The host to connect to; required.port: The HTTP port to connect to; defaults to8123unlesshostis a ClickHouse Cloud host, in which case it defaults to8443dbname: The name of the database to connect to.username: The username to connect as; defaults todefaultpassword: The password to use to authenticate; defaults to no password
Useful for queries that return no records, but queries that do return values will be returned as a single text value:
Pushdown Functions
All PostgreSQL builtin functions used in conditionals (HAVING and WHERE
clauses) to query ClickHouse foreign tables automatically push down to
ClickHouse with the same names and signatures. However, some have different
names or signatures and must be mapped to their equivalents. pg_clickhouse
maps the following functions:
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
array_position: indexOfbtrim: trimBothstrpos: positionregexp_like: match
Custom Functions
These custom functions created by pg_clickhouse provide foreign query
pushdown for select ClickHouse functions with no PostgreSQL equivalents. If
any of these functions cannot be pushed down they will raise an exception.
Pushdown Casts
pg_clickhouse pushes down casts such as CAST(x AS bigint) for compatible
data types. For incompatible types the pushdown will fail; if x in this
example is a ClickHouse UInt64, ClickHouse will refuse to cast the value.
In order to push down casts to incompatible data types, pg_clickhouse provides the following functions. They raise an exception in PostgreSQL if they are not pushed down.
Pushdown Aggregates
These PostgreSQL aggregate functions pushdown to ClickHouse.
Custom Aggregates
These custom aggregate functions created by pg_clickhouse provide foreign
query pushdown for select ClickHouse aggregate functions with no PostgreSQL
equivalents. If any of these functions cannot be pushed down they will raise
an exception.
Pushdown Ordered Set Aggregates
These ordered-set aggregate functions map to ClickHouse Parametric
aggregate functions by passing their direct argument as a parameter and
their ORDER BY expressions as arguments. For example, this PostgreSQL query:
Maps to this ClickHouse query:
Note that the non-default ORDER BY suffixes DESC and NULLS FIRST
are not supported and will raise an error.
percentile_cont(double): quantilequantile(double): quantilequantileExact(double): quantileExact
Authors
Copyright
Copyright (c) 2025-2026, ClickHouse
"PostgreSQL Docs: Shared Library Preloading [PREPARE notes]: https://www.postgresql.org/docs/current/sql-prepare.html#SQL-PREPARE-NOTES "PostgreSQL Docs: PREPARE notes" [query parameters]: https://clickhouse.com/docs/guides/developer/stored-procedures-and-prepared-statements#alternatives-to-prepared-statements-in-clickhouse "ClickHouse Docs: Alternatives to prepared statements in ClickHouse"