> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentación de referencia completa del módulo chdb_hook de Postgres

# Documentación de referencia del módulo chdb_hook

<h2 id="synopsis">
  Sinopsis
</h2>

```psql theme={null}
# LOAD 'chdb_hook';
LOAD

# CREATE TABLE times (
    id     INT NOT NULL,
    months INT NOT NULL,
    days   INT NOT NULL
);
CREATE TABLE

# COPY times FROM 's3://datasets-documentation/my-test-bucket-768/{some,another}_prefix/some_file_{1..3}.csv';
COPY 18
```

<h2 id="description">
  Descripción
</h2>

El módulo chdb\_hook se engancha al comando [COPY](#copy-overloading) de
PostgreSQL para usar [chDB] y copiar datos `TO` o `FROM` cualquiera de los
[formatos de datos compatibles que ofrece chDB][formats], ya sea en archivos
locales, buckets de [AWS S3], [Google Cloud Storage] y más. También se engancha
a [CREATE TABLE], de modo que una tabla puede derivar sus columnas y cargar
sus filas desde cualquiera de esos mismos destinos.

<h2 id="loading">
  Carga
</h2>

Cargue chdb\_hook de una de las siguientes maneras como super user. Utilice la
que resulte más adecuada para su caso de uso:

* Explícitamente mediante el comando [LOAD]; se mantiene durante toda la session:

  ```sql theme={null}
  LOAD 'chdb_hook';
  ```

  <Note>
    La SQL Console de ClickHouse Cloud aún no admite el comando `LOAD 'chdb_hook'`,
    pero puede ejecutarse mediante psql o cualquier otra conexión a la base de datos.
    De lo contrario, póngase en contacto con su representante de soporte para añadirlo
    a la configuración de su service de Postgres, tras lo cual podrá utilizarse en la
    SQL Console.
  </Note>

* Para todas las sessions, mediante el setting \[session\_preload\_libraries], en
  `postgresql.conf`:

  ```ini theme={null}
  session_preload_libraries = chdb_hook
  ```

  O mediante [ALTER SYSTEM]:

  ```sql theme={null}
  ALTER SYSTEM SET session_preload_libraries = 'chdb_hook';
  ```

  Este setting también puede establecerse por base de datos mediante [ALTER DATABASE]:

  ```sql theme={null}
  ALTER DATABASE name SET session_preload_libraries = 'chdb_hook';
  ```

  O para usuarios y grupos específicos mediante [ALTER ROLE]:

  ```sql theme={null}
  ALTER ROLE name SET session_preload_libraries = 'chdb_hook';
  ```

* Al iniciar el servidor, mediante el setting \[shared\_preload\_libraries], de modo que
  esté siempre disponible para todas las sessions y bases de datos:

  ```ini theme={null}
  shared_preload_libraries = chdb_hook
  ```

<Warning>
  Tenga en cuenta que cargar chdb\_hook permite a los usuarios con los roles `pg_read_server_files`
  o `pg_write_server_files` ejecutar `COPY` para copiar datos desde y hacia archivos del
  servidor de Postgres, así como en almacenamiento en la nube.
</Warning>

<h2 id="copy-overloading">
  Sobrecarga de COPY
</h2>

Durante la [carga](#loading), chdb\_hook se engancha al comando [COPY] de Postgres para
copiar datos `TO` o `FROM` cualquiera de los [formatos de datos compatibles que proporciona
chDB][formats] en archivos locales, buckets de [AWS S3], [Google Cloud Storage] y
más. Por ejemplo, para cargar una tabla desde un archivo CSV en S3, cree la tabla
y luego llame a `COPY` con una URL `s3://`:

```sql theme={null}
CREATE TABLE times (
    id     INT PRIMARY KEY,
    months INT NOT NULL,
    days   INT NOT NULL
);

COPY times FROM 's3://datasets-documentation/my-test-bucket-768/some_prefix/some_file_1.csv';
```

<h3 id="privileges">
  Privilegios
</h3>

Un `COPY` de chdb\_hook requiere los mismos privilegios que el [COPY] al que reemplaza:
`SELECT` sobre la relación o sobre cada columna copiada en el caso de `COPY TO`, e `INSERT`
en el de `COPY FROM`. Una URL `file://` lee o escribe un archivo en el servidor, por lo que
también exige pertenecer a `pg_read_server_files` o `pg_write_server_files`.
`COPY FROM` requiere una transacción de lectura-escritura.

<h3 id="url-schemes">
  Esquemas de URL
</h3>

chdb\_hook solo se ejecuta para destinos `COPY` de tipo URL que utilicen uno de los
siguientes esquemas:

| Esquemas | Destino | Función de chDB |
| - | - | - |
| `file` | Ruta absoluta en el servidor de Postgres | [`file()`] |
| `http`, `https` | URL HTTP | [`url()`] |
| `s3` | [AWS S3] | [`s3()`] |
| `gs`, `gcs`, `oss` | [Google Cloud Storage] | [`gcs()`] |
| `az`, `azure`, `abfss`, `abfs` | [Azure Blob Storage] o [Azure ABFS] | [`azureBlobStorage()`] |
| `hdfs` | [Hadoop Distributed File System] | [`hdfs()`] |

<h3 id="url-formats">
  Formatos de URL
</h3>

El formato de las URL varía según el destino.

<h4 id="file">
  File
</h4>

Debe ser una ruta absoluta en el servidor de Postgres. Una ruta relativa provoca un
error. El usuario de Postgres debe ser miembro del rol `pg_read_server_files` o
`pg_write_server_files`, según corresponda. El usuario del sistema de Postgres debe
tener acceso de lectura o escritura al archivo, según corresponda. En el caso de `COPY TO`, si la
ruta no existe, chdb\_hook creará los directorios padre que falten; para ello debe
contar con los permisos necesarios en el sistema de archivos. Ejemplo:

```
file:///tmp/users.parquet
```

<h4 id="http">
  HTTP
</h4>

Cualquier URL HTTP normal, incluidas las de almacenamiento en la nube público. Para `COPY TO`,
chdb\_hook intentará enviar los datos a la URL mediante `POST`. Ejemplo:

```
https://datasets-documentation.s3.eu-west-3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_1.csv
```

<h4 id="s3">
  S3
</h4>

Las URL de S3 pueden tener la forma de un URI de S3

```
s3://{bucket}/{path}
```

O de una URL de objeto:

```
s3://{bucket}.s3.{region}.amazonaws.com/{path}
```

<h4 id="GCS">
  GCS
</h4>

Las URL de GCS tienen el formato de una URL pública:

```
gs://storage.googleapis.com/{bucket}/{path}
```

O un URI de Cloud Storage, que chdb\_hook convierte en una URL pública:

```
gs://{bucket}/{path}
```

<h4 id="azure-blob-storage">
  Azure Blob Storage
</h4>

Utilice una URL `blob.windows.net` con el nombre de la cuenta como subdominio:

```
az://{account}.blob.core.windows.net/{container}/{blob}
```

O utilice otro nombre del host:

```
az://{host}/{container}/{blob}
```

<h4 id="azure-abfs">
  Azure ABFS
</h4>

Las URL de ABFS deben usar este formato:

```
abfs://{container}@{account}.dfs.core.windows.net/{blob}
```

<h4 id="hdfs-urls">
  URL de HDFS
</h4>

Las URL de HDFS pueden usar URL con el estilo típico de HTTP y un puerto opcional:

```
hdfs://{host}/{path}
hdfs://{host}:{port}/{path}
```

<h3 id="path-wildcards">
  Comodines de ruta
</h3>

Las rutas URL pueden contener globs en los comandos `COPY FROM`. Los archivos deben coincidir con
el patrón de ruta completo, no solo con el sufijo o el prefijo. La única excepción: cuando
la ruta hace referencia a un directorio existente y no usa globs, se añadirá implícitamente un `*`
a la ruta para seleccionar todos los archivos del directorio.

Comodines admitidos:

* `*`: Coincide con cualquier cantidad de caracteres excepto `/`, incluida la cadena vacía.
* `?`: Coincide con un único carácter arbitrario.
* `{groucho,harpo,chico}`: Sustituye cualquiera de las cadenas "groucho", "harpo" y
  "chico". Las cadenas pueden contener `/`.
* `{N..M}`: Coincide con cualquier número `>= N` y `<= M`.
* `**`: Coincide recursivamente con todos los archivos de un directorio.

Por ejemplo, para cargar datos de estos archivos con un solo comando:

* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;1.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;1.csv)
* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;2.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;2.csv)
* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;3.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some\&#95;prefix/some\&#95;file\&#95;3.csv)
* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;1.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;1.csv)
* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;2.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;2.csv)
* [https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;3.csv](https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another\&#95;prefix/some\&#95;file\&#95;3.csv)

Use `{some,another}_prefix` para hacer coincidir los dos nombres de directorio y
`some_file_{1..3}.csv'` para los archivos, de este modo:

```sql theme={null}
CREATE TABLE times (
    id     INT NOT NULL,
    months INT NOT NULL,
    days   INT NOT NULL
);

COPY times FROM 's3://datasets-documentation/my-test-bucket-768/{some,another}_prefix/some_file_{1..3}.csv';
```

<h3 id="options">
  Opciones
</h3>

El comando `COPY` de chdb\_hook admite las siguientes opciones:

<h4 id="format">
  `format`:
</h4>

El formato de lectura o escritura. Debe ser uno de los [formats] que ofrece [chDB],
entre los que se incluyen TSV, CSV, Parquet, Iceberg, JSON y otros. Omítalo o establézcalo en
`auto` para que chDB determine el formato a partir de la extensión del nombre del archivo al final
de la URL.

<h4 id="structure">
  `structure`
</h4>

La estructura de datos de [chDB] para una fila. Consta de una lista de nombres de columnas,
\[tipos de datos de ClickHouse] y modificadores. Si se omite, chdb\_hook asigna los tipos de
datos de Postgres a tipos de ClickHouse generalmente apropiados; consulte [Postgres a
chDB](#postgres-to-chdb) para más detalles. Si se establece en `auto`, chDB intenta inferir
los tipos.

Ejemplo:

```sql theme={null}
COPY users TO 'file:///tmp/users.parquet' (
    structure 'id Int64, name String, age Nullable(UInt8), attributes JSON'
);
```

<h4 id="access_key-and-access_secret">
  `access_key` y `access_secret`
</h4>

Credenciales de larga duración del usuario de la cuenta de AWS para autenticar las solicitudes.

* **S3:** Un \[ID de clave de acceso y clave secreta de acceso] de AWS, definidos habitualmente mediante las variables de entorno `AWS_ACCESS_KEY_ID` y `AWS_SECRET_ACCESS_KEY`
* **GCS:** Una \[clave HMAC y su secreto] de GCP
* **Azure:** Un nombre de cuenta de Azure Storage y su \[clave de acceso]

<h4 id="session_token">
  `session_token`
</h4>

Token de sesión de AWS que se usa junto con `access_key` y `access_secret`, definido
habitualmente por la variable de entorno `AWS_SESSION_TOKEN`. Se utiliza únicamente para
URL de S3.

<h4 id="compression">
  `compression`
</h4>

Formato de compresión del archivo. Úselo si la compresión no puede inferirse a partir del
nombre del archivo. Valores admitidos:

* `auto` (predeterminado)
* `none`
* `gzip` o `gz`
* `brotli` o `br`
* `xz` o `LZMA`
* `zstd` o `zst`
* `lz4`
* `bz2`
* `snappy`

<h4 id="timeout">
  `timeout`
</h4>

Tiempo de espera de la solicitud en milisegundos. Se aplica a las URL de HTTP, S3, GCS y Azure.
El valor predeterminado es `30000` (30 s).

<h3 id="debugging">
  Depuración
</h3>

Cuando se produce un error, el comando `COPY` de chdb\_hook incluye en el contexto del error la consulta de [chDB] que intentó
ejecutar:

```
ERROR:  chdb: error executing chDB query
DETAIL:  Code: 53. DB::Exception: Requested type of column p doesn't match parquet schema
CONTEXT:  query: SELECT * FROM file({path:String}, {format:String}, {structure:String})
STATEMENT:  COPY "users" FROM 'file:///tmp/users.data' (format 'Parquet');
```

chdb\_hook utiliza placeholders con el estilo `{name:Type}` para los parámetros de consulta
con el fin de protegerse frente a vulnerabilidades de injection de SQL y minimizar el riesgo de
registrar datos sensibles como credenciales.

No obstante, si necesitas ver el contenido de esos parámetros para depurar
un issue, configura temporalmente el GUC \[log\_min\_messages] de Postgres con el valor `DEBUG1` o
superior para que chdb\_hook envíe la consulta y los parámetros al log de Postgres
(nunca al client), donde aparecerán así:

```
2026-08-08 09:41:06.842 EDT [59940] LOG:  executing chDB query
2026-08-08 09:41:06.842 EDT [59940] DETAIL:  query: SELECT * FROM file({path:String}, {format:String}, {structure:String})
2026-08-08 09:41:06.842 EDT [59940] CONTEXT:  params: { path: "/tmp/users.data", format: "Parquet", structure: "user_id Nullable(Int64), username Nullable(String), password Nullable(String)" }
2026-08-08 09:41:06.842 EDT [59940] STATEMENT:  COPY "users" FROM 'file:///tmp/users.data' (format 'Parquet');
```

<Warning>
  No mantenga \[log\_min\_messages] en un nivel de depuración más allá de
  una única sesión de depuración, tanto para evitar registrar información sensible como
  las credenciales, como porque el propio PostgreSQL también registra información de depuración
  y puede llenar el log con rapidez.
</Warning>

<h2 id="create-table-overloading">
  Sobrecarga de CREATE TABLE
</h2>

chdb\_hook también se engancha a [CREATE TABLE], de modo que una tabla puede derivar sus columnas y cargar sus filas desde una URL.

Para crear una tabla cuya estructura se derive de una URL, pase la URL en la
opción `structure_from` y deje vacía la lista de columnas:

```sql theme={null}
CREATE TABLE reviews () WITH (
    structure_from = 's3://datasets-documentation/amazon_reviews/amazon_reviews_2015.snappy.parquet'
);
```

Use `copy_from` para cargar tanto las filas como las columnas:

```sql theme={null}
CREATE TABLE reviews () WITH (
    copy_from = 's3://datasets-documentation/amazon_reviews/amazon_reviews_2015.snappy.parquet'
);
```

`copy_from` infiere las columnas solo cuando el statement no declara ninguna propia.
Una lista de columnas, un clause `INHERITS`, un type `OF` o una partición definen
columnas, por lo que, en ese caso, `copy_from` solo copia:

```sql theme={null}
CREATE TABLE times (
    id     INT NOT NULL,
    months INT NOT NULL,
    days   INT NOT NULL
) WITH (copy_from = 's3://datasets-documentation/my-test-bucket-768/some_prefix/some_file_1.csv');
```

Ambas opciones admiten los mismos [esquemas de URL](#url-schemes) y las mismas
[opciones](#options) que `COPY`: se aplican las credenciales, el formato, la
compresión, el timeout e incluso una [estructura](#structure) explícita. Postgres
conserva los parámetros de almacenamiento restantes:

```sql theme={null}
CREATE TABLE users () WITH (
    copy_from     = 's3://my-bucket/users.csv',
    access_key    = 'AKIAIOSFODNN7EXAMPLE',
    access_secret = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    format        = 'CSVWithNames',
    fillfactor    = 90
);
```

Ni `structure_from` ni `copy_from` funcionan con `IF NOT EXISTS`. Utilice
[COPY] para cargar una relación existente.

<h2 id="limitations">
  Limitaciones
</h2>

Debido a algunos problemas conocidos y a las variaciones en el comportamiento de los tipos de datos
entre Postgres y chDB, chdb\_hook presenta las siguientes limitaciones:

* No se puede hacer `COPY` de relaciones con políticas de [row-level security] que se apliquen al
  rol que realiza la copia. Postgres aplica dichas políticas reescribiendo `COPY TO` como una
  consulta, algo que chdb\_hook no admite.
* ClickHouse no tiene un array NULL, por lo que `COPY TO` almacena un array vacío (`[]`) en lugar de
  un `NULL`.
* ClickHouse representa los equivalentes de `lseg`, `path` o `polygon` como
  arrays; por lo tanto, los valores NULL de estos tipos también se escriben con `COPY TO` como un array vacío
  (`[]`).
* Los valores NULL emitidos para una [structure](#structure) especificada que no
  defina la columna como Nullable se emitirán como sus valores predeterminados. Defina siempre
  explícitamente las columnas nullable en la [structure](#structure) para evitar
  esta conversión.
* Un `path` abierto cuyo último punto coincide con el primero se emite como un path cerrado.
* Protobuf no admite null en un campo repetido, por lo que omite los valores NULL en los arrays.
* El [JSON type] de chDB solo admite objetos JSON; sobrescriba la correspondencia predeterminada
  `String` de `json` y `jsonb` con `JSON` únicamente si todos los valores son
  objetos JSON. (ClickHouse/ClickHouse#68428)
* El [JSON type] de chDB ignora los `null`; las claves de objeto con valores NULL se
  omitirán en la salida. Sobrescriba la correspondencia predeterminada `String` de `json` y
  `jsonb` con `JSON` únicamente si los valores del objeto no son `null` o si su pérdida resulta
  aceptable. (ClickHouse/ClickHouse#68428)
* Los formatos JSON, JSONCompact y JSONColumnsWithMetadata siempre validan
  UTF-8, por lo que emiten los valores bytea con caracteres de reemplazo.
* `COPY FROM` lee como `NULL` un campo `Nullable` de Protobuf que contenga una cadena vacía o
  un cero. (chdb-io/chdb-core#152)
* `COPY TO` en Parquet descarta los `NULL` del propio null map de un Tuple Nullable.
  (ClickHouse/ClickHouse#112427)
* Los formatos Parquet, Arrow, ArrowStream, ORC, Avro, Protobuf, ProtobufList, MsgPack
  y BSONEachRow no tienen un tipo equivalente al `time` de Postgres ni
  al `Time64` de chDB. Configure las columnas `time` como `String` en una
  [structure](#structure) explícita para preservar sus valores.
* La salida de Protobuf trunca los valores de timestamp al segundo.
* La salida de Protobuf no admite fechas anteriores al 1970-01-01. Configure las columnas `time`
  como `String` en una [structure](#structure) explícita para preservar
  sus valores. (ClickHouse/ClickHouse#111860)
* Los formatos CSVWithNames y CSVWithNamesAndTypes no pueden importar actualmente
  valores box o circle `NULL`. (ClickHouse/ClickHouse#115523)

<h2 id="data-types">
  Tipos de datos
</h2>

[COPY](#copy-overloading) asigna los tipos de Postgres de una relación a tipos de chDB,
mientras que [CREATE TABLE](#create-table-overloading) asigna los tipos de chDB de una URL
a tipos de Postgres.

<h3 id="postgres-to-chdb">
  Postgres a chDB
</h3>

Si no se especifica explícitamente la opción [structure](#structure), chdb\_hook asigna
los tipos de Postgres a equivalentes razonables de chDB. Cuando no se ajusten a su
caso de uso, indique [structure](#structure) para sobrescribir los tipos generados con
los que necesite.

| Postgres | chDB | Notas |
| - | - | - |
| boolean | Bool | |
| name | String | |
| text | String | |
| inet | String | Sobrescriba con `IPv4` o `IPv6` si los datos contienen solo uno de los dos. |
| cidr | String | |
| macaddr | String | |
| macaddr8 | String | |
| interval | String | Sobrescriba con una unidad `Interval` como `IntervalDay`. |
| tsvector | String | |
| tsquery | String | |
| jsonpath | String | |
| money | String | |
| enum | String | |
| varchar | String | |
| varbit | String | |
| char | FixedString | |
| bit | FixedString | |
| bpchar | String | |
| int2 | Int16 | |
| int4 | Int32 | |
| int8 | Int64 | |
| oid | UInt32 | |
| oid8 | UInt64 | |
| xid8 | UInt64 | |
| json | String | Sobrescriba con `JSON` si los datos contienen solo objetos. |
| jsonb | String | Sobrescriba con `JSON` si los datos contienen solo objetos. |
| float4 | Float32 | |
| float8 | Float64 | |
| date | Date32 | |
| time | Time64(6) | Sobrescriba con `String` para formatos que no admitan horas. |
| timetz | String | |
| timestamp | DateTime64(6) | Se declara con la zona horaria `UTC` y se convierte desde la zona horaria de la sesión. |
| timestamptz | DateTime64(6) | Se declara con la zona horaria `UTC`. |
| numeric | Decimal | |
| uuid | UUID | |
| point | `Point` | Las mismas dos coordenadas que en Postgres. |
| lseg | `LineString` | Una línea de exactamente dos puntos. |
| path | `LineString` | Una ruta cerrada repite su primer punto. |
| polygon | `Ring` | Un anillo se cierra de forma implícita, igual que un polígono. |
| box | `Tuple(high Point, low Point)` | Las dos esquinas, con el mismo orden que aplica Postgres. |
| circle | `Tuple(center Point, radius Float64)` | |
| line | `Tuple(a Float64, b Float64, c Float64)` | La ecuación `Ax + By + C = 0`. |

Los tipos array se asignan a `Array`s del tipo de elemento correspondiente. ClickHouse restringe
la nulabilidad por columna, mientras que Postgres lo hace por array, de modo que los elementos son
siempre `Nullable`.

Ningún tipo de Postgres se asigna a `Map` ni a `Tuple`, pero [structure](#structure) puede
indicar uno. Un `Map` puede convertirse en un array de pares clave-valor, y un `Tuple`
se convierte en un array. Use `text[]` para admitir datos heterogéneos.

<h3 id="timestamp-conversion">
  Conversión de timestamp
</h3>

En formatos de texto plano (TSV, CSV, etc.), el hook `COPY` emite los valores DateTime y
DateTime64 en formato ISO-8601, `YYYY-MM-DDThh:mm:ssZ`, sin tener en cuenta
la configuración actual de `datestyle`. Esto garantiza que los valores timestamptz
se mantengan coherentes, incluso si un origen que importa los valores usa una zona
horaria distinta. Usar un tipo diferente en la salida de `structure`, como `Datetime64(3,
'America/Los_Angeles')`, no afecta al desplazamiento de la salida, pero sí
cambia la precision.

Ejemplos de timestamp TZ:

| timestamptz | `DateTime64(6, 'UTC')` | `DateTime64(3 'Japan')` |
| - | - | - |
| `2026-08-28T12:00:00Z` | `2026-08-28T12:00:00.000000Z` | `2026-08-28T12:00:00.000Z` |
| `2026-08-28T11:00:00 America/Los_Angeles` | `2026-08-28T18:00:00.000000Z` | `2026-08-28T18:00:00.000Z` |
| `2026-08-28T10:00:00.723923 Asia/Tokyo` | `2026-08-28T01:00:00.723923Z` | `2026-08-28T01:00:00.723Z` |

El hook `COPY` también convierte los valores timestamp de la session zona horaria a
UTC, con lo que se garantiza que se emitan en relación con esa zona horaria. Al cargarlos
en un sistema nuevo, este debería convertirlos a su zona horaria local. Por tanto, los
valores diferirán si la zona horaria difiere, pero serán equivalentes respecto a
la diferencia de zona horaria.

Ejemplo del efecto de la configuración `timezone` sobre el timestamp
`2026-08-28T12:00:00`:

| configuración de timezone | `DateTime64(6, 'UTC')` | `DateTime64(3 'Japan')` |
| - | - | - |
| `UTC` | `2026-08-28T12:00:00.000000Z` | `2026-08-28T12:00:00.000Z` |
| `America/Los_Angeles` | `2026-08-28T19:00:00.000000Z` | `2026-08-28T19:00:00.000Z` |
| `America/New_York` | `2026-08-28T16:00:00.000000Z` | `2026-08-28T16:00:00.000Z` |
| `Japan` | `2026-08-28T03:00:00.000000Z` | `2026-08-28T03:00:00.000Z` |

<h3 id="chdb-to-postgres">
  chDB a Postgres
</h3>

chdb\_hook asigna los tipos de ClickHouse devueltos por [`DESCRIBE`] a estos
tipos de Postgres:

| chDB | Postgres | Notas |
| - | - | - |
| Array(T) | T\[] | Un tipo array de PG por nivel de anidamiento |
| BFloat16 | real | La escritura descarta los bits bajos de la mantisa |
| Bool | boolean | |
| Date | date | |
| Date32 | date | |
| DateTime | timestamp with time zone | |
| DateTime64(P) | timestamp(P) with time zone | Un P mayor que 6 se limita a 6 |
| Decimal(P,S) | numeric(P,S) | |
| Decimal32(S) | numeric(9,S) | |
| Decimal64(S) | numeric(18,S) | |
| Decimal128(S) | numeric(38,S) | |
| Decimal256(S) | numeric(76,S) | |
| Enum8 | text | |
| Enum16 | text | |
| FixedString(N) | text | N cuenta bytes en CH y caracteres en PG |
| Float32 | real | |
| Float64 | double precision | |
| IPv4 | inet | |
| IPv6 | inet | |
| Int8 | smallint | |
| Int16 | smallint | |
| Int32 | integer | |
| Int64 | bigint | |
| Int128 | numeric(39,0) | |
| Int256 | numeric(77,0) | |
| IntervalDay | interval | |
| IntervalHour | interval | |
| IntervalMicrosecond | interval | |
| IntervalMillisecond | interval | |
| IntervalMinute | interval | |
| IntervalMonth | interval | |
| IntervalNanosecond | interval | Se trunca a microsegundos |
| IntervalQuarter | interval | |
| IntervalSecond | interval | |
| IntervalWeek | interval | |
| IntervalYear | interval | |
| JSON | jsonb | |
| LineString | path | |
| LowCardinality(T) | T | |
| Map(K,V) | text\[]\[] | Una fila de elementos de texto por par |
| MultiLineString | path\[] | |
| MultiPolygon | polygon\[]\[] | |
| Nullable(T) | T | Marca la columna como nullable |
| Point | point | |
| Polygon | polygon\[] | |
| Ring | polygon | |
| String | text | |
| Time | time without time zone | |
| Time64(P) | time(P) without time zone | Un P mayor que 6 se limita a 6 |
| Tuple(...) | text\[] | Los campos pasan a ser elementos de texto |
| UInt8 | smallint | |
| UInt16 | integer | |
| UInt32 | bigint | |
| UInt64 | numeric(20,0) | |
| UInt128 | numeric(39,0) | |
| UInt256 | numeric(78,0) | |
| UUID | uuid | |

Todo tipo de chDB omitido en esta tabla lanza un error, entre ellos `Nested`,
`Variant` y `Dynamic`. Use una [structure](#structure) que los asigne a
`String` para leerlos como texto.

Postgres admite un rango más estrecho que chDB en algunos de estos tipos; por
ello, la copia lanza un error con un `Time` o `Time64` que supere las 24 horas,
y con un `Date32` fuera del rango de fechas de Postgres.

<h3 id="text-encoding">
  Codificación de texto
</h3>

chDB lee `String`, `FixedString`, `Enum` y `JSON` como bytes, sin
ninguna garantía de codificación. Al copiar una columna de ese tipo a `text`, o a cualquier otro
tipo no binario, se verifican los bytes según la codificación de la base de datos y se lanza un error
para los datos que no se pueden representar:

```
ERROR:  invalid byte sequence for encoding "UTF8": 0x00
```

Todas las codificaciones rechazan los NUL, que Postgres no puede almacenar en `text`.

Copia en `bytea` para conservar los bytes tal como los escribió chDB. Nombra así estos casos, ya que
[CREATE TABLE](#create-table-overloading) deriva `text` para estos tipos:

```sql theme={null}
CREATE TABLE logs (id bigint, payload bytea) WITH (
    copy_from = 's3://my-bucket/logs.parquet'
);
```

`FixedString(N)` rellena con bytes NUL los valores más cortos. Al copiarlos a `text` se descartan los NUL finales, mientras que `bytea` conserva los N bytes.

<h2 id="settings">
  Configuración
</h2>

<h3 id="chdb_hookmax_memory">
  `chdb_hook.max_memory`
</h3>

```sql theme={null}
SET chdb_hook.max_memory = '1 GB';
```

Define la cantidad máxima de memoria para una consulta de chDB y se utiliza para establecer el ajuste
[`max_memory_usage`] de chDB. Requiere privilegios de superuser. Utilice un número entero
para indicar la cantidad de megabytes o una de las siguientes unidades de memoria:

* `B` (bytes)
* `kB` (kilobytes)
* `MB` (megabytes)
* `GB` (gigabytes)
* `TB` (terabytes)

El valor predeterminado es `0`, que no impone ningún límite de memoria.

<h3 id="chdb_hookmax_threads">
  `chdb_hook.max_threads`
</h3>

```sql theme={null}
SET chdb_hook.max_threads = 4;
```

El número máximo de subprocesos de procesamiento de consultas para una consulta de chDB, que se usa para establecer el ajuste [`max_threads`] de chDB. Requiere privilegios de superusuario. Su valor predeterminado es `0`, lo que permite que chDB determine el valor.

Recomendamos encarecidamente configurar `chdb_hook.max_threads` antes de ejecutar un `COPY` de gran tamaño, para evitar que chDB agote el uso de CPU en detrimento de PostgreSQL.

<h3 id="chdb_hookmax_parsing_threads">
  `chdb_hook.max_parsing_threads`
</h3>

```sql theme={null}
SET chdb_hook.max_parsing_threads = 2;
```

El número máximo de subprocesos que chDB puede usar para parsear datos en formatos de entrada que
admiten parsing en paralelo; se utiliza para definir el ajuste [`max_parsing_threads`]
de chDB. Requiere privilegios de superusuario. Su valor predeterminado es `0`, lo que permite que chDB
determine el valor.

Recomendamos definir `chdb_hook.max_parsing_threads` antes de ejecutar un `COPY` con grandes volúmenes de
datos, para evitar que chDB acapare el uso de CPU en detrimento de
PostgreSQL.

<h2 id="versioning-policy">
  Política de control de versiones
</h2>

chdb\_hook sigue el [control de versiones semántico] en sus releases públicas.

* La versión mayor se incrementa ante cambios en la API
* La versión menor se incrementa ante cambios de SQL retrocompatibles
* La versión de patch se incrementa ante cambios que solo afectan al binary

Una vez instalado, PostgreSQL la versión mediante la función
[`pg_get_loaded_modules()`] de Postgres 18.

```sql theme={null}
SELECT version FROM pg_get_loaded_modules() WHERE module_name = 'chdb_hook';
```

<h2 id="authors">
  Autores
</h2>

* [David E. Wheeler](https://justatheory.com/)
* [serprex](https://github.com/serprex)

<h2 id="copyright">
  Derechos de autor
</h2>

Copyright (c) 2026, ClickHouse

[chDB]: https://clickhouse.com/chdb "chDB: base de datos in-process rápida, fiable y escalable"

[control de versiones semántico]: https://semver.org/spec/v2.0.0.html "control de versiones semántico 2.0.0"

[COPY]: https://www.postgresql.org/docs/current/sql-copy.html "Documentación de Postgres: COPY"

[CREATE TABLE]: https://www.postgresql.org/docs/current/sql-createtable.html "Documentación de Postgres: CREATE TABLE"

[`DESCRIBE`]: https://clickhouse.com/docs/sql-reference/statements/describe-table "ClickHouse Docs: DESCRIBE TABLE"

[formats]: https://github.com/chdb-io/chdb/blob/main/refs/clickhouse-formats-settings.md#complete-format-names-table "Documentación de chDB: tabla completa de nombres de formatos"

[access key ID and access secret]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html "AWS Identity and Access Management: administrar claves de acceso para usuarios de IAM"

[HMAC key and secret]: https://docs.cloud.google.com/storage/docs/authentication/hmackeys "Google Cloud Storage: claves HMAC"

[access key]: https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-cli "Azure: administrar las claves de acceso de la cuenta de almacenamiento"

[row-level security]: https://www.postgresql.org/docs/current/ddl-rowsecurity.html "Documentación de Postgres: políticas de seguridad a nivel de fila"

[JSON type]: /reference/data-types/newjson "ClickHouse Docs: tipo de datos JSON"

[LOAD]: https://www.postgresql.org/docs/current/sql-load.html "Documentación de Postgres: LOAD"

[session_preload_libraries]: https://www.postgresql.org/docs/18/runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES "Documentación de Postgres: `session_preload_libraries`"

[shared_preload_libraries]: https://www.postgresql.org/docs/18/runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES "Documentación de Postgres: `shared_preload_libraries`"

[ALTER SYSTEM]: https://www.postgresql.org/docs/18/sql-altersystem.html "Documentación de Postgres: ALTER SYSTEM"

[ALTER DATABASE]: https://www.postgresql.org/docs/current/sql-alterdatabase.html "Documentación de Postgres: ALTER DATABASE"

[ALTER ROLE]: https://www.postgresql.org/docs/18/sql-alterrole.html "Documentación de Postgres: ALTER ROLE"

[AWS S3]: https://aws.amazon.com/s3/ "Cloud Object Storage - Amazon S3 - Amazon Web Services"

[Google Cloud Storage]: https://cloud.google.com/storage "Cloud Storage - Google Cloud"

[`file()`]: https://clickhouse.com/docs/sql-reference/table-functions/file "ClickHouse Docs: función de tabla file"

[`url()`]: https://clickhouse.com/docs/sql-reference/table-functions/url "ClickHouse Docs: función de tabla url"

[`s3()`]: https://clickhouse.com/docs/sql-reference/table-functions/s3 "ClickHouse Docs: función de tabla s3"

[`gcs()`]: https://clickhouse.com/docs/sql-reference/table-functions/gcs "ClickHouse Docs: función de tabla gcs"

[Azure Blob Storage]: https://azure.microsoft.com/en-us/products/storage/blobs/

[Azure ABFS]: https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-introduction-abfs-uri "Uso del URI de Azure Data Lake Storage (ABFS) - Azure Storage"

[`azureBlobStorage()`]: https://clickhouse.com/docs/sql-reference/table-functions/azureBlobStorage "ClickHouse Docs: función de tabla azureBlobStorage"

[Hadoop Distributed File System]: https://en.wikipedia.org/wiki/Apache_Hadoop#Overview "Wikipedia: descripción general de Apache Hadoop"

[`hdfs()`]: https://clickhouse.com/docs/sql-reference/table-functions/hdfs "ClickHouse Docs: función de tabla hdfs"

[ClickHouse data types]: https://clickhouse.com/docs/reference/data-types/index "ClickHouse Docs: tipos de datos en ClickHouse"

[log_min_messages]: https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-MIN-MESSAGES "Documentación de PostgreSQL: log_min_messages"

[`pg_get_loaded_modules()`]: https://pgpedia.info/g/pg_get_loaded_modules.html "pgPedia: pg_get_loaded_modules()"

[`max_memory_usage`]: https://clickhouse.com/docs/reference/settings/session-settings/max-memory-usage "ClickHouse Docs: session settings max_memory_usage_*"

[`max_threads`]: https://clickhouse.com/docs/reference/settings/session-settings/max-threads "ClickHouse Docs: session settings max_threads_*"

[`max_parsing_threads`]: https://clickhouse.com/docs/reference/settings/session-settings/max#max_parsing_threads "ClickHouse Docs: session setting max_parsing_threads"
