Descripción
pg_clickhouse es una extensión de PostgreSQL que permite ejecutar consultas de forma remota en bases de datos de ClickHouse, e incluye un foreign data wrapper. Es compatible con PostgreSQL 14 y versiones posteriores, y con ClickHouse 23.3 y versiones posteriores.Primeros pasos
La forma más sencilla de probar pg_clickhouse es la [imagen de Docker], que contiene la imagen estándar de PostgreSQL para Docker con las extensiones pg_clickhouse y [re2][re2 extension]:Uso
Política de versionado
pg_clickhouse sigue Semantic Versioning para sus versiones públicas.- La versión principal se incrementa con cambios en la API
- La versión secundaria se incrementa con cambios de SQL compatibles con versiones anteriores
- La versión de parche se incrementa con cambios solo en el binario
- La versión de la biblioteca (definida por
PG_MODULE_MAGICen PostgreSQL 18 y posteriores) incluye la versión semántica completa, visible en la salida de la funciónpgch_version()o de la función de Postgrespg_get_loaded_modules(). - La versión de la extensión (definida en el archivo de control) incluye solo las versiones principal
y secundaria, visibles en la tabla
pg_catalog.pg_extension, la salida de la funciónpg_available_extension_versions()y\dx pg_clickhouse.
v0.1.0 a v0.1.1, beneficia a todas las bases de datos que han cargado v0.1 y
no necesitan ejecutar ALTER EXTENSION para aprovechar la actualización.
Por otro lado, una versión que incrementa las versiones secundaria o principal
irá acompañada de scripts de actualización de SQL, y todas las bases de datos existentes que contengan
la extensión deben ejecutar ALTER EXTENSION pg_clickhouse UPDATE para aprovechar
la actualización.
Referencia de SQL DDL
Las siguientes expresiones DDL de SQL usan pg_clickhouse.CREATE EXTENSION
Usa CREATE EXTENSION para añadir pg_clickhouse a una base de datos:WITH SCHEMA para instalarlo en un esquema concreto (recomendado):
ALTER EXTENSION
Use ALTER EXTENSION para modificar pg_clickhouse. Ejemplos:-
Después de instalar una nueva versión de pg_clickhouse, use la cláusula
UPDATE: -
Use
SET SCHEMApara mover la extensión a un nuevo esquema:
DROP EXTENSION
Utiliza DROP EXTENSION para eliminar pg_clickhouse de una base de datos:CASCADE para eliminarlos también:
CREATE SERVER
Utilice CREATE SERVER para crear un servidor foráneo que se conecta a un servidor de ClickHouse. Ejemplo:driver: El driver de conexión de ClickHouse que se va a usar, ya sea “binary” o “http”. Obligatorio.compression: Compresión del protocolo nativo para el driver “binary”, una de “none”, “lz4” o “zstd”. El valor predeterminado es “lz4”. El driver “http” la ignora.dbname: La base de datos en ClickHouse que se usará al conectarse. El valor predeterminado es “default”.host: El nombre de host del servidor de ClickHouse. El valor predeterminado es “localhost”;port: El puerto del servidor de ClickHouse al que conectarse. Los valores predeterminados son los siguientes:- 9440 si
driveres “binary” yhostes un host de ClickHouse Cloud - 9004 si
driveres “binary” yhostno es un host de ClickHouse Cloud - 8443 si
driveres “http” yhostes un host de ClickHouse Cloud - 8123 si
driveres “http” yhostno es un host de ClickHouse Cloud
- 9440 si
min_tls_version: Versión mínima del protocolo TLS que se negociará en las conexiones que usan TLS. Una deTLSv1,TLSv1.1,TLSv1.2oTLSv1.3. El valor predeterminado es el mínimo propio de la biblioteca TLS. Se aplica a ambos drivers.secure: Controla TLS para la conexión. Uno de:auto(predeterminado): usa TLS cuandohostes un host de ClickHouse Cloud oportes un puerto seguro; texto no cifrado en caso contrario.on(otrue/yes/1): usa siempre TLS.porttoma por defecto el valor 8443 (“http”) o 9440 (“binary”).off(ofalse/no/0): no usa nunca TLS.porttoma por defecto el valor 8123 (“http”) o 9000 (“binary”).
encoding_check: Define cómo tratar los caracteres no válidos según la [codificación de la base de datos] al convertir valores String y JSON de ClickHouse. Uno de:fail(predeterminado): genera un errorremoveelimina los bytes no válidosreplace: con la codificación UTF-8, sustituye los bytes no válidos por el carácter de reemplazo de Unicode (�); equivale aremoveen otras codificacionestruncatetrunca el texto en el primer byte no válido
ALTER SERVER
Use ALTER SERVER para modificar un servidor foráneo. Ejemplo:DROP SERVER
Use DROP SERVER para eliminar un servidor foráneo:CASCADE para
eliminar también esas dependencias:
CREATE USER MAPPING
Utilice CREATE USER MAPPING para asignar un usuario de PostgreSQL a un usuario de ClickHouse. Por ejemplo, para asignar el usuario actual de PostgreSQL al usuario remoto de ClickHouse al conectarse al servidor foráneotaxi_srv:
user: El nombre del usuario de ClickHouse. El valor predeterminado es “default”.password: La contraseña del usuario de ClickHouse.
ALTER USER MAPPING
Use ALTER USER MAPPING para cambiar la definición de una asignación de usuario:DROP USER MAPPING
Utilice DROP USER MAPPING para eliminar una asignación de usuario:IMPORT FOREIGN SCHEMA
Utilice IMPORT FOREIGN SCHEMA para importar todas las tablas definidas en una base de datos en ClickHouse como tablas foráneas en un esquema de PostgreSQL:LIMIT TO para limitar la importación a tablas específicas:
EXCEPT para excluir tablas:
-
Las columnas importadas conservan el modificador de tipo del tipo de ClickHouse, incluidos
los que se encuentran dentro de
Arrays. Es decir,Array(Decimal(12,6))se importa comonumeric(12,6)[]. -
Las columnas
Nullablese importan sinNOT NULL; en cambio,Nullabledentro de unArrayno tiene ese efecto, porque los arrays de PostgreSQL siempre admiten elementos NULL. -
Las columnas
AggregateFunctionySimpleAggregateFunctionse importan sinNOT NULL, independientemente de la declaración en ClickHouse; consulte Columnas de estado andNOT NULL. -
Las columnas
Tuplese importan comotext[]. Las columnasMapy las columnasNestedcreadas conflatten_nested=0se importan comotext[][]. Cada conversión emite unNOTICE. El pseudotiporecordde PostgreSQL no puede definir una columna de tabla, por lo que cada tupla se convierte en un array de valores, cada mapa en un array bidimensional de pares clave-valor y cada valor Nested en un array bidimensional de filas. Para leer los campos como registros, cambie el tipo de la columna a un array de un tipo compuesto equivalente; consulte Manual Type Mappings para ver un ejemplo. -
Las columnas
DateTime64yTime64con una precisión superior a 6 (microsegundos) también generan unNOTICE, ya que PostgreSQL limita la precisión atimestamp(6)ytime(6). -
Los tipos de columna sin equivalente en PostgreSQL, incluido el tipo heredado
Object('json'), anterior aJSONde ClickHouse, generan un error.
CREATE FOREIGN TABLE
Utilice CREATE FOREIGN TABLE para crear una tabla foránea que permita consultar datos de una base de datos en ClickHouse:database: El nombre de la base de datos remota. De forma predeterminada, usa la base de datos definida para el servidor foráneo.table_name: El nombre de la tabla remota. De forma predeterminada, usa el nombre especificado para la tabla foránea.engine: El [motor de tabla] usado por la tabla de ClickHouse. ParaCollapsingMergeTree()yAggregatingMergeTree(), pg_clickhouse aplica automáticamente los parámetros a las expresiones de función ejecutadas en la tabla.
-
column_name: El nombre de la columna en el lado de ClickHouse, usado con preferencia al nombre del atributo de PostgreSQL al reconstruir consultas e inserciones. Es útil para mapear nombres de columna de PostgreSQL en minúsculas y sin comillas a columnas de ClickHouse sensibles a mayúsculas y minúsculas; por ejemplo, -
AggregateFunction: El nombre de la función de agregación aplicada a una columna de [tipo AggregateFunction]. Mapee el tipo de dato al tipo de ClickHouse pasado a la función y especifique el nombre de la función de agregación mediante la opción de columna adecuada; pg_clickhouse añadirá automáticamenteMergea la función de agregación que evalúe la columna. Declare la columna como nullable para evitar los problemas descritos en Columnas de estado yNOT NULL. -
SimpleAggregateFunction: El nombre de la función de agregación aplicada a una columna de [tipo SimpleAggregateFunction]. Mapee el tipo de dato al tipo de ClickHouse pasado a la función y especifique el nombre de la función de agregación mediante la opción de columna adecuada.
Columnas de estado y NOT NULL
Mantenga las columnas AggregateFunction y SimpleAggregateFunction como Nullable.
PostgreSQL 19 reemplaza count(column) por count(*) en las columnas de estado
NOT NULL, lo que cuenta filas en lugar de fusionar estados.
Considere una tabla de ClickHouse que almacena un estado count por usuario, cada uno generado
a partir de 1000 eventos:
NOT NULL, PostgreSQL cuenta los estados, lo que da como resultado un recuento no válido:
NOT NULL, pg_clickhouse usa countMerge() para fusionar los estados, con lo que
se obtiene el recuento correcto de 1000:
ALTER FOREIGN TABLE para eliminar la restricción de una tabla foránea existente:
NOT NULL solo afecta a PostgreSQL. Por eso, IMPORT FOREIGN
SCHEMA importa las columnas de estado como columnas Nullable.
ALTER FOREIGN TABLE
Use ALTER FOREIGN TABLE para cambiar la definición de una tabla foránea:DROP FOREIGN TABLE
Utilice DROP FOREIGN TABLE para eliminar una tabla foránea:CASCADE para eliminarlos también:
Referencia de SQL DML
Las expresiones SQL DML que aparecen a continuación pueden usar pg_clickhouse. Los ejemplos dependen de estas tablas de ClickHouse:EXPLAIN
El comando EXPLAIN funciona como es de esperar, pero la opciónVERBOSE provoca que se emita la
consulta de ClickHouse “Remote SQL”:
SELECT
Use la instrucción SELECT para ejecutar consultas en las tablas pg_clickhouse igual que en cualquier otra tabla:nodes y hacemos un JOIN con ella en lugar de con la tabla remota:
node_id en lugar de por la columna local, y luego hacer el join
con la tabla de búsqueda más adelante:
node_id, lo que reduce
el número de filas que deben volver a Postgres de 1000 (todas
ellas) a solo 8, una por cada nodo.
Tablas particionadas
Una [tabla particionada] de PostgreSQL puede combinar particiones locales con particiones externas respaldadas por ClickHouse. Una configuración habitual traslada los datos más antiguos a ClickHouse, mientras que los datos recientes permanecen en PostgreSQL:enable_partitionwise_aggregate habilitado, PostgreSQL calcula una agregación
parcial debajo de Append y, a continuación, una agregación de finalización encima combina esos
resultados parciales en el resultado final. pg_clickhouse envía la agregación parcial de la partición externa
a ClickHouse:
Cuándo se hace pushdown de agregaciones parciales
PostgreSQL representa una agregación parcial como un estado de transición que el paso de finalización combina entre particiones. pg_clickhouse puede hacer pushdown de la agregación parcial de una partición solo cuando puede expresarla como un valor de ClickHouse:- Agregaciones descomponibles cuyo estado de transición ya es el valor
final, se envían directamente mediante pushdown:
count,sum,min,max,bool_and/every,bool_or,bit_and,bit_orybit_xor. avgsobre enteros envía mediante pushdown su estado{count, sum}como un array.avg,var_pop,var_samp,stddev_popystddev_sampsobre números de punto flotante envían mediante pushdown su estado{N, sum, suma de desviaciones al cuadrado}como un array.
FILTER (WHERE …) se envía mediante pushdown con estas funciones de agregación.
Cuándo recurren a una alternativa
Las agregaciones cuyo estado de transición es el tipo opacointernal de PostgreSQL no tienen una representación portable, por lo que la partición externa obtiene sus filas y las agrega localmente. Esto incluye cualquier agregación sobre numeric, además de avg(bigint) y avg(interval). Las agregaciones DISTINCT, de conjuntos ordenados y variádicas también recurren a una alternativa.
PREPARE, EXECUTE, DEALLOCATE
A partir de la versión v0.1.2, pg_clickhouse admite consultas parametrizadas, que se crean principalmente con el comando PREPARE:{param:type}:
INSERT
Utilice el comando INSERT para insertar valores en una tabla remota de ClickHouse:COPY
Utiliza el comando COPY para insertar un lote de filas en una tabla remota de ClickHouse:⚠️ Limitaciones de la API de inserción por lotes pg_clickhouse aún no admite la API de inserción por lotes del FDW de PostgreSQL. Por lo tanto, COPY utiliza actualmente sentencias INSERT para insertar registros. Esto se mejorará en una futura versión.
LOAD
Utilice LOAD para cargar la biblioteca compartida pg_clickhouse:SET
Use SET para establecer los parámetros de configuración personalizados de pg_clickhouse.pg_clickhouse.session_settings
El parámetro pg_clickhouse.session_settings configura la [configuración de ClickHouse] que se establecerá en las consultas posteriores. Ejemplo:
join_use_nulls para las combinaciones externas y transform_null_in para la familia
IN (consulte IN y semántica de NULL).
date_time_output_format: el driver HTTP requiere que sea “iso”format_tsv_null_representation: el driver HTTP requiere el valor predeterminadooutput_format_tsv_crlf_end_of_lineel driver HTTP requiere el valor predeterminado
pg_clickhouse.session_settings; use precarga de bibliotecas compartidas o
simplemente use uno de los objetos de la extensión para asegurarse de que se cargue.
pg_clickhouse.pushdown_regex
El parámetro pg_clickhouse.pushdown_regex controla si pg_clickhouse
realiza pushdown de las funciones y los operadores de expresiones regulares. Lo hace de forma predeterminada;
establezca este parámetro en false para evitarlo:
ALTER ROLE
Use el comandoSET de ALTER ROLE para precargar pg_clickhouse
y/o SET sus parámetros para determinados roles:
RESET de ALTER ROLE para restablecer la precarga de pg_clickhouse
y/o los parámetros:
Precarga
Si todas o casi todas las conexiones a Postgres necesitan usar pg_clickhouse, considere usar la precarga de bibliotecas compartidas para que se cargue automáticamente:session_preload_libraries
Carga la biblioteca compartida en cada nueva conexión a PostgreSQL:
shared_preload_libraries
Carga la biblioteca compartida en el proceso principal de PostgreSQL durante el arranque:
Tipos de datos
Esta tabla presenta la correspondencia preferida entre los tipos de datos de ClickHouse y PostgreSQL. IMPORT FOREIGN SCHEMA utiliza estas correspondencias y deriva a partir de ellas los modificadores de tipo y las dimensiones de array adecuados. Use CREATE FOREIGN TABLE para declarar tipos de PostgreSQL alternativos. La columna de destinos de lectura adicionales enumera las conversiones que admite el controladorbinary, además
de las conversiones explícitas de PostgreSQL. Las celdas vacías no impiden esas conversiones. Los valores deben
caber en los tipos de destino. Estos destinos se refieren a las lecturas; las escrituras siguen reglas de
conversión propias.
Cualquier columna también se puede leer como
text, varchar u otro tipo de cadena. El valor
adopta el tipo de PostgreSQL indicado arriba y luego se representa mediante la función de salida
de ese tipo. Una cadena de ClickHouse leída como un tipo de texto se valida con la
codificación de la base de datos, por lo que los bytes que PostgreSQL no puede leer generan un error. Declare una columna
String, FixedString, Enum o JSON como BYTEA para leer sus bytes tal como
ClickHouse los escribió.
Los tipos compatibles con la entrada pueden leer cadenas mediante su función de entrada de PostgreSQL.
Los tipos compuestos deben tener los mismos campos en el mismo orden. Para leer una tupla
como un array, cada campo debe poder convertirse al tipo de elemento del array, y ningún campo
puede ser, a su vez, un array.
Cuando se leen como arrays, Map usa una fila por cada par clave-valor y Nested usa
una fila por cada registro anidado. Para leer una tupla como box, proporcione dos puntos; para
circle, un punto y un radio; y para line, tres coeficientes.
A continuación se incluyen notas y detalles adicionales.
Coerción de tipos
Con el controladorbinary, los tipos escalares alternativos usan las conversiones
explícitas de PostgreSQL cuando están disponibles, y los elementos de array se convierten
al tipo de elemento declarado. Las conversiones no compatibles y los valores fuera de rango generan errores.
Con cualquiera de los dos controladores, asigne los tipos Interval de ClickHouse a smallint, integer
o bigint para leer y escribir el recuento de sus unidades. Por ejemplo, un
valor IntervalDay de 3 corresponde al integer 3. Si se asigna
IntervalNanosecond a bigint, se conservan los nanosegundos, mientras que si se asigna a
interval, el valor se trunca a microsegundos.
BYTEA
ClickHouse no ofrece un equivalente al tipo BYTEA de PostgreSQL, pero permite almacenar cualquier secuencia de bytes en el tipo [String]. En general, las cadenas de ClickHouse deben mapearse al tipo [TEXT] de PostgreSQL; sin embargo, cuando se trabaja con datos binarios, deben mapearse al tipo BYTEA. Ejemplo:SELECT final generará:
FixedString(N) rellena los valores cortos con bytes nulos. Una columna de texto
descarta ese relleno final, mientras que una columna BYTEA conserva todos los bytes.
Tipos compuestos
Array
Los [Array] de ClickHouse se corresponden directamente con los arrays de PostgreSQL, con una semántica equivalente. La principal diferencia es que, en Postgres, los arrays multidimensionales deben tener expresiones de array con dimensiones coincidentes. Si se intenta leer un array de ClickHouse con dimensiones distintas, como[[1], [2,3]],
se produce un error.
El acceso por índice a los arrays hace pushdown cuando corresponde, incluido el acceso
por índice multidimensional. Ejemplos:
Map
PostgreSQL no ofrece ningún tipo equivalente al tipo [Map] de ClickHouse. Por ello, pg_clickhouse asigna las columnas [Map] atext[][], de modo que cada par clave-valor
se representa como un array independiente. IMPORT FOREIGN SCHEMA utiliza
esta correspondencia. Asimismo, es posible usar INSERT para insertar mapas como arrays. Por ejemplo:
Para insertar un
Map se requiere el controlador binary, que obtiene los tipos de columna
del servidor de ClickHouse. El controlador http no lo hace, por lo que carece de la
información necesaria para formatear e insertar el valor adecuado.Tuple
Del mismo modo, las columnas [Tuple] de ClickHouse se asignan atext[] y admiten operaciones INSERT
mediante el controlador binario. IMPORT FOREIGN SCHEMA emite un NOTICE cuando establece
dicha correspondencia.
Nested
De forma predeterminada, ClickHouse divide una columnaNested en una columna Array por
cada campo (flatten_nested=1). IMPORT FOREIGN SCHEMA lee estas columnas del catálogo
system.columns de ClickHouse y crea columnas de array independientes en PostgreSQL,
conservando los nombres con puntos, como items.a e items.b. Por ejemplo,
dada esta tabla externa:
WHERE con las funcionalidades habituales de los arrays,
incluida la sintaxis de subíndices de array:
flatten_nested=0 se corresponde con un array con un
elemento por cada fila anidada. Cada elemento del array contiene los valores de esa fila:
c2 Nested(id Int64, name String) de este ejemplo, quedaría así:
text[][] sobre tipos Nested falla:
Correspondencias manuales de tipos
IMPORT FOREIGN SCHEMA utiliza tipos genéricos de PostgreSQL. Por ejemplo,
dada una tabla de ClickHouse con columnas [Enum], [Tuple], Map y [Nested]
no aplanadas (flatten_nested = 0), como la siguiente:
key y value en
este caso). Nested y Map se convierten en arrays de tipos compuestos, mientras que Tuple
se convierte en un único valor compuesto:
SELECT:
WHERE, siempre que los nombres de los campos sean
idénticos:
INSERT con este tipo de tipos compuestos.
Referencia de funciones y operadores
Funciones
Estas funciones proporcionan la interfaz para realizar consultas a una base de datos de ClickHouse.clickhouse_server_version
major.minor.patch, del
servidor externo indicado; si es necesario, se conecta mediante las opciones del servidor y la
asignación de usuario del usuario actual:
SELECT version(), y la almacena en caché durante la vida de la
conexión.
clickhouse_query
driver del servidor,
las credenciales, la base de datos y la caché de conexiones.
El primer argumento es el nombre de un servidor creado con CREATE SERVER. Se
requiere una lista de definición de columnas (AS name(col type, ...)): PostgreSQL necesita
conocer la estructura del resultado antes de obtener las filas, y debe coincidir con las columnas que devuelve la consulta. Los valores se convierten de ClickHouse a los tipos declarados del mismo modo
que los de una columna de tabla externa. Las sentencias que no devuelven resultados, como las DDL,
no tienen nada que declarar; ejecútelas con
clickhouse_perform.
Ningún rol tiene acceso EXECUTE de forma predeterminada; use GRANT para conceder a un rol permiso para usar
la función.
clickhouse_perform
clickhouse_query no tiene una estructura del resultado que declarar. Resuelve
el servidor del mismo modo que clickhouse_query y reutiliza su
driver, credenciales, base de datos y caché de conexión.
Como procedimiento, debe invocarse con CALL, no con SELECT, y no devuelve
filas. Ningún rol tiene acceso EXECUTE de forma predeterminada; conceda GRANT a un rol
para permitirle usar el procedimiento.
Funciones pushdown
pg_clickhouse aplica pushdown a un subconjunto de las funciones integradas de PostgreSQL que se usan en condicionales (cláusulasHAVING y WHERE). Ese subconjunto se corresponde con los
equivalentes en ClickHouse de la siguiente manera:
abs: absfactorial: factorialmod(int2/int4/int8/numeric): módulopow&power(float8, no numeric): powround: roundsin,cos,tan,atan,atan2,sinh,cosh,tanh,asinh,degrees,radians,pi: funciones matemáticas de ClickHouse con el mismo nombre.asin,acos,atanh,acoshno se delegan: PG produce un error con entradas fuera de rango, mientras que CH devuelveNaN.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): mismas equivalencias quedate_partdate(timestamp)&date(timestamptz): toDate (se muestra como alias de CHdate)array_position: indexOf con nullIf para convertir0enNULLy arraySlice cuando hay un tercer argumento para el índice inicial de búsqueda; ten en cuenta que actualmentenanno coincidearray_cat: arrayConcatarray_append: arrayPushBackarray_prepend: arrayPushFrontarray_remove: arrayRemovecardinality: arrayFlattenedLength en ClickHouse 26.9+; en caso contrario, length, que solo cuenta el array exteriorarray_length(array, 1):nullIf(length(array), 0)array_length&cardinality: lengtharray_to_string: arrayStringConcatstring_to_array: splitByStringsplit_part: splitByString + subíndice del arraytrim_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 si la expresión regular contiene subexpresiones entre paréntesis; en caso contrario, extractAll recortado con arraySlice.regexp_replace: replaceRegexpOne o replaceRegexpOne cuando está presente la marcagregexp_split_to_array: splitByRegexpmd5: MD5sha224,sha256,sha384ysha512: Las funciones SHA correspondientes de ClickHouseencode(bytea, fmt)cuandofmtes una constante de cadena (sin distinción entre mayúsculas y minúsculas):encode(bytea, 'hex'): hex envuelto en lower, ya que PostgreSQL genera valores hexadecimales en minúsculas.encode(bytea, 'base64'): base64Encode envuelto en replaceRegexpAll para reproducir los saltos de línea MIME (RFC 2045) de PostgreSQL cada 76 caracteres.encode(bytea, 'base64url')(PostgreSQL 19+): base64URLEncode, que coincide con el alfabeto de URL de RFC 4648 de PostgreSQL sin padding.
json_extract_path_text: sintaxis de subcolumnasjson_extract_path: toJSONString + sintaxis de subcolumnasjsonb_extract_path_text: sintaxis de subcolumnasjsonb_extract_path: toJSONString + sintaxis de subcolumnasbit_count(bytea): bitCountto_timestamp(float8): toDateTime64to_char(timestamp[tz], fmt): formatDateTime cuandofmtes una constante de cadena cuyas palabras clave tienen cada una un equivalente fiel en ClickHouse. Consulta to_char() en las Notas de compatibilidad para ver las palabras clave admitidas. En caso contrario, la función se evalúa localmente en PostgreSQL.statement_timestamp,transaction_timestamp, &clock_timestamp: nowInBlock64 (nowInBlock64(9, $session_timezone))CURRENT_DATE: now y 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: Se pasa como valor desde una función de PostgreSQL.CURRENT_SCHEMA: Se pasa como valor de la función de PostgreSQL.CURRENT_CATALOG: Se pasa como valor desde una función de PostgreSQL.CURRENT_USER: Se pasa como valor desde una función de PostgreSQL.USER: Se pasa como valor desde una función de PostgreSQL.CURRENT_ROLE: Se pasa como valor desde la función de PostgreSQL.SESSION_USER: Se pasa como valor de la función de PostgreSQL.
Operadores pushdown
- Segmento de Array (
arr[L:U]): arraySlice @>(el array contiene): hasAll<@(array contenido en): hasAll&&(solapamiento de arrays): hasAny~(coincidencia de regexp): match!~(sin coincidencia de regexp): match~*(regexp sin distinguir mayúsculas de minúsculas, sin coincidencia): match!~*(regexp sin distinguir mayúsculas de minúsculas, sin coincidencia): match->>(extraer elemento de JSON/JSONB como texto): sintaxis de subcolumnas->(extracción de JSON/JSONB): toJSONString + sintaxis de subcolumnas
Semántica de IN y NULL
ClickHouse evalúaIN con lógica de dos valores: cuando la comprobación no encuentra
ninguna coincidencia, devuelve 0 incluso si interviene un NULL, mientras que PostgreSQL calcula
NULL. Para preservar la semántica de PostgreSQL, pg_clickhouse hace pushdown de la familia
IN sobre una lista o un array constantes (IN, NOT IN, = ANY, = ALL, <> ANY, <> ALL) de forma incondicional: usa la forma nativa o de bajo coste cuando puede
demostrar que ni la comprobación ni un elemento del array pueden ser NULL, o bien una forma
CASE con protección en caso contrario, que comprueba los valores NULL en tiempo de ejecución
y calcula la respuesta exacta de tres valores de PostgreSQL (TRUE, FALSE, NULL) en
cualquier contexto, incluidas posiciones de valor como una lista SELECT o GROUP BY.
Un filtro NOT IN (SELECT ...) sobre columnas que admiten NULL también hace pushdown,
y se desanaliza con protecciones compensatorias que preservan el comportamiento de PostgreSQL: un conjunto
que contiene un NULL descalifica todas las filas, y una comprobación NULL solo pasa
frente a un conjunto vacío. Cada protección se omite cuando una declaración NOT NULL
demuestra que no es necesaria. A diferencia de las formas de array anteriores, esta protección solo
se aplica en una condición de filtro simple (o bajo NOT); seguimos sin hacer pushdown
de IN (SELECT ...) (en una posición de valor) ni de cuerpos de subconsultas
agrupados o agregados. Declarar las columnas como NOT NULL maximiza el pushdown, ya que permite
enviar en su lugar la forma sin protección, más económica; IMPORT FOREIGN SCHEMA lo hace automáticamente para
las columnas de ClickHouse que no son Nullable. La comprobación sigue las constantes no NULL,
las columnas NOT NULL y la aritmética básica (+, -, *, - unario) aplicada a ellas.
Estas reglas presuponen el valor predeterminado de ClickHouse transform_null_in = 0, que
pg_clickhouse establece en cada consulta mediante el valor predeterminado del
parámetro pg_clickhouse.session_settings,
para que un perfil del servidor ClickHouse no pueda modificarlo silenciosamente. Establecer
transform_null_in = 1 rompe la semántica de todos los IN a los que se les hace pushdown.
Funciones personalizadas
Estas funciones personalizadas creadas por pg_clickhouse permiten el pushdown de consultas externas para ciertas funciones de ClickHouse que no tienen equivalentes en PostgreSQL. Si alguna de estas funciones no puede enviarse mediante pushdown, lanzará una excepción.Pushdown de extensiones
pg_clickhouse reconoce funciones de ciertas extensiones principales y de terceros y las envía a sus equivalentes en ClickHouse.re2
Todos los operadores y funciones de la [extensión re2] hacen pushdown 1:1 a ClickHouse:@~→ matchre2match→ matchre2extract→ extractre2extractall→ extractAllre2regexpextract→ regexpExtractre2extractgroups→ extractGroupsre2replaceregexpone→ replaceRegexpOnere2replaceregexpall→ replaceRegexpAllre2countmatches→ countMatchesre2countmatchescaseinsensitive→ countMatchesCaseInsensitivere2multimatchany→ multiMatchAnyre2multimatchanyindex→ multiMatchAnyIndexre2multimatchallindices→ multiMatchAllIndices
intarray
Una función de [intarray] hace pushdown a ClickHouse:idx→ indexOf
fuzzystrmatch
Dos funciones de [fuzzystrmatch] hacen pushdown a ClickHouse:soundex: soundexlevenshtein(2-arg): editDistanceUTF8
pgcyrpto
digest(text, text)ydigest(bytea, text): la función hash de ClickHouse correspondiente cuando el algoritmo es una constantemd5,sha1,sha224,sha256,sha384osha512(sin distinguir entre mayúsculas y minúsculas).
Conversiones de tipos con pushdown
pg_clickhouse aplica pushdown a conversiones de tipos comoCAST(x AS bigint) para
tipos de datos compatibles. En el caso de tipos incompatibles, el pushdown fallará; si x en este
ejemplo es un UInt64 de ClickHouse, ClickHouse se negará a convertir el valor.
Para aplicar pushdown a conversiones de tipos a tipos de datos incompatibles, pg_clickhouse proporciona
las siguientes funciones. Generan una excepción en PostgreSQL si no se
aplican con pushdown.
Funciones de agregación con pushdown
Estas funciones de agregación de PostgreSQL admiten pushdown en 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
Agregados personalizados
Estas funciones de agregación personalizadas creadas por pg_clickhouse permiten el pushdown de consultas externas para determinadas funciones de agregación de ClickHouse que no tienen equivalentes en PostgreSQL. Si alguna de estas funciones no puede aplicarse mediante pushdown, generará una excepción.Pushdown de funciones de agregación de conjuntos ordenados
Estas funciones de agregación de conjuntos ordenados se corresponden con las [funciones de agregación paramétricas] de ClickHouse al pasar su argumento directo como parámetro y sus expresionesORDER BY como argumentos. Por ejemplo, esta consulta de PostgreSQL:
ORDER BY, DESC y NULLS FIRST
no son compatibles y provocarán un error.
percentile_cont(double): quantilepercentile_cont(double[]): quantilespercentile_disc(double): quantileExactLowpercentile_disc(double[]): quantilesExactLow
Funciones de agregación de conjuntos ordenados personalizadas
Estas funciones de agregación de conjuntos ordenados personalizadas creadas por pg_clickhouse permiten hacer pushdown de consultas externas para determinadas [funciones de agregación paramétricas] de ClickHouse. Si no se puede hacer pushdown de alguna de estas funciones, se generará una excepción.quantile(double): quantilequantileExact(double): quantileExact
Funciones de agregación de conjuntos ordenados personalizadas
Estas funciones de agregación de conjuntos ordenados personalizadas creadas por pg_clickhouse permiten el pushdown de consultas externas para determinadas funciones de [agregación paramétricas] de ClickHouse. Si no se puede hacer pushdown de alguna de estas funciones, se generará una excepción.Funciones de ventana con pushdown
Estas [funciones de ventana] de PostgreSQL se ejecutan mediante pushdown en ClickHouse con cláusulasOVER (PARTITION BY ... ORDER BY ...), incluidas las especificaciones de marco
cuando corresponde.
- row_number
- rank
- dense_rank
- ntile
- cume_dist
- percent_rank
- lead
- lag
- first_value
- last_value
- nth_value
min/max(con la cláusulaOVER)
row_number, rank, dense_rank, ntile, cume_dist,
percent_rank) omiten la cláusula de marco durante el pushdown porque ClickHouse
rechaza las especificaciones de marco para estas funciones.
Notas de compatibilidad
Expresiones regulares
Aunque pg_clickhouse aplica pushdown de las expresiones regulares a equivalentes de ClickHouse cuando pg_clickhouse.pushdown_regex es true (el valor predeterminado), y se esfuerza por garantizar un nivel básico de compatibilidad, tenga en cuenta las diferencias entre ambos y cómo las gestiona pg_clickhouse.-
PostgreSQL admite [expresiones regulares POSIX], mientras que ClickHouse admite
[expresiones regulares RE2][RE2]. Tenga cuidado con las diferencias de comportamiento: use RE2
cuando la expresión regular vaya a ser evaluada por ClickHouse (p. ej., en una
cláusula
WHERE) y POSIX cuando vaya a ser evaluada por Postgres (p. ej., en una cláusulaSELECT). -
pg_clickhouse hace pushdown de los [indicadores de Postgres] al anteponerlos a la expresión regular de ClickHouse dentro de
(?). Por ejemplo:Pasa a ser -
Los únicos indicadores que admiten ambos y que, por lo tanto, pueden usarse al ser evaluados por
ClickHouse son:
RE2 solo admite estos modificadores; no uses otros [modificadores de Postgres].
-
Esta tabla resume los efectos de los distintos modificadores (y de no usar ninguno, que
equivale a
s) al hacer coincidir saltos de línea y finales de línea. Tenga en cuenta que en Postgres,mypimpiden que las clases de caracteres negadas ([^xyz]) coincidan con un salto de línea, mientras que los equivalentes de ClickHouse no. Por lo demás, el comportamiento es el mismo en ClickHouse que en Postgres: - Cualquier otro indicador pasado a las funciones de expresiones regulares impedirá el pushdown de la función.
-
La excepción es
regexp_replace(), que también admite el indicadorg. Cuandogestá activado, pg_clickhouse usareplaceRegexpAll()en lugar dereplaceRegexpOne()y elimina el indicador antes de anteponer otros indicadores. -
El argumento de reemplazo de
regexp_replace()de Postgres admite\¶ referirse a la coincidencia completa, mientras que en ClickHouse se usa\0para la coincidencia completa. Asegúrate de usar\0cuando la función haga pushdown a ClickHouse. -
Postgres
regexp_matchdevuelveNULLcuando no hay coincidencias, mientras que las expresiones a las que se les hace pushdown devuelven un arreglo vacío. UseCOALESCE()para devolver un arreglo vacío en lugar deNULLy así poder comparar los valores devueltos de forma compatible. Por ejemplo:
to_char()
PostgreSQL [to_char()] para timestamp y timestamp with time zone solo hace
pushdown a ClickHouse [formatDateTime] cuando el argumento de formato es una
constante de cadena no NULL en la que todas las palabras clave de PostgreSQL
tienen un equivalente idéntico byte por byte en ClickHouse. Si el formato es dinámico o contiene alguna
palabra clave o modificador no admitido, la llamada vuelve a evaluarse localmente en
PostgreSQL. pg_clickhouse nunca hace pushdown de una traducción parcial, por lo que la salida
sigue siendo compatible.
Las variantes de to_char() de dos argumentos sobre numeric, interval y otros
tipos que no son de marca de tiempo nunca hacen pushdown; ClickHouse [formatDateTime] solo
da formato a valores de fecha y hora.
Palabras clave traducidas
Texto y literales entre comillas
El texto entrecomillado con"..." se pasa literalmente, y cualquier % literal se duplica
como %% para escapar el prefijo de especificador de ClickHouse. Un \" fuera de las comillas también
se pasa como un " literal. Dentro de "...", la barra invertida solo escapa ";
las demás secuencias con barra invertida se tratan como texto literal.
Autores
David E. WheelerDerechos de autor
Derechos de autor (c) 2025-2026, ClickHouse [Array] https://clickhouse.com/docs/reference/data-types/array “Documentación de ClickHouse: Array(T)” [Map]: https://clickhouse.com/docs/sql-reference/data-types/map “Documentación de ClickHouse: Map” [Tuple]: https://clickhouse.com/docs/reference/data-types/tuple “Documentación de ClickHouse: Tuple(T1, T2, …)” [Nested]: https://clickhouse.com/docs/sql-reference/data-types/nested-data-structures/nested “Documentación de ClickHouse: Nested” [Enum]: https://clickhouse.com/docs/reference/data-types/enum “Documentación de ClickHouse: Enum” [String]: /reference/data-types/string “Documentación de ClickHouse: String” [TEXT]: https://www.postgresql.org/docs/current/datatype-character.html “Documentación de PostgreSQL: Tipos de caracteres” [window functions]: https://www.postgresql.org/docs/current/functions-window.html “Documentación de PostgreSQL: Funciones de ventana” [POSIX Regular Expressions]: https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-POSIX-REGEXP “Documentación de PostgreSQL: Expresiones regulares POSIX” [Postgres flags]: https://www.postgresql.org/docs/current/functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE “Documentación de PostgreSQL: Letras de opciones integradas de ARE” [RE2]: https://github.com/google/re2/wiki/Syntax “Sintaxis de RE2” [extensión re2]: https://github.com/ClickHouse/pg_re2 “pg_re2: funciones de expresiones regulares compatibles con ClickHouse que usan RE2” [intarray]: https://www.postgresql.org/docs/current/intarray.html “Documentación de PostgreSQL: intarray” [fuzzystrmatch]: https://www.postgresql.org/docs/current/fuzzystrmatch.html “Documentación de PostgreSQL: fuzzystrmatch” [to_char()]: https://www.postgresql.org/docs/current/functions-formatting.html “Documentación de PostgreSQL: Funciones de formato de tipos de datos”
[formatDateTime]: /reference/functions/regular-functions/date-time-functions#formatDateTime “Documentación de ClickHouse: formatDateTime”