Able to read many data types that exist in both Postgres and DuckDB. The following data types are currently supported for use in queries:
- Integer types (
integer,bigint, etc.) - Floating point types (
real,double precision) numeric(might get converted todouble precisioninternally see known limitations below for details)text/varchar/bpcharbytea/blobtimestamp/timstampz/date/interval/timestamp_ns/timestamp_ms/timestamp_sbooleanuuidjson/jsonbarraysfor all of the above types, but see limitations below about multi-dimensional arrays
The type support in pg_duckdb is not yet complete (and might never be). The
following are known issues that you might run into. Feel free to contribute PRs
to fix these limitations:
enumtypes are not supported (PR is progress)- The DuckDB
decimaltype doesn't support the wide range of values that the Postgresnumerictype does. To avoid errors when converting between the two,numericis converted todouble precisioninternally ifDuckDBdoes not support the required precision. Obviously this might cause precision loss of the values. - The DuckDB
STRUCTtype is not supported - The DuckDB
timestamp_nstype gets truncated to microseconds when it is converted to the Postgrestimestamptype, which loses precision in the output. Operations on atimestamp_nsvalue, such as sorting/grouping/comparing, will use the full precision. jsonbcolumns are converted tojsoncolumns when reading from DuckDB. This is because DuckDB does not have ajsonbtype.- Many Postgres
jsonandjsonbfunctions and operators are not implemented in DuckDB. Instead you can use DuckDB json functions and operators. See the DuckDB documentation for more information on these functions. - The DuckDB
tinyinttype is converted to achartype in Postgres. This is because Postgres does not have atinyinttype. This causes it to be displayed as a hex code instead of a regular number. - Conversion between in Postgres multi-dimensional arrays and DuckDB nested
LISTs in DuckDB can run into various problems, because neither database supports the thing that the other supports exactly. Specifically in Postgres it's allowed for different arrays in a column to have a different number of dimensions, e.g.[1]and[[1], [2]]can both occur in the same column. In DuckDB that's not allowed, i.e. the amount of nesting should always be the same. On the other hand, in DuckDB it's valid for different lists at the same nest-level to contain a different number of elements, e.g.[[1], [1, 2]. This is not allowed in Postgres. So conversion between these types is only possible when the arrays follow the subset. Another possible problem that you can run into is that pg_duckdb uses the Postgres column metadata to determine the number of dimensions that an array has. Since Postgres doesn't complain when you add arrays of different dimensions, it's possible that the number of dimensions in the column metadata does not match the actual number of dimensions. To solve this you need to alter the column type:-- This configures the column to be a 3-dimensional array of text ALTER TABLE s ALTER COLUMN a SET DATA TYPE text[][][];
pg_duckdb introduces a few special Postgres types. You shouldn't create these types explicitly and normally you don't need to know about their existence, but they might show up in error messages from Postgres. These are explained below:
The duckdb.row type is returned by functions like read_parquet, read_csv, scan_iceberg, etc. Depending on the arguments of these functions they can return rows with different columns and types. Postgres doesn't support such functions well at this point in time, so for now we return a custom type from them. To then be able to get the actual columns out of these rows you have to use the "square bracket indexing" syntax, similarly to how you would get field
SELECT r['id'], r['name'] FROM read_parquet('file.parquet') r WHERE r['age'] > 21;Using SELECT * will result in the columns of this row being expanded, so your query result will never have a column that has duckdb.row as its type:
SELECT * FROM read_parquet('file.parquet');The duckdb.unresolved_type type is a type that is used to make Postgres understand an expression for which the type is not known at query parse time. This is the type of any of the columns extracted from a duckdb.row using the r['mycol'] syntax. Many operators and aggregates will return a duckdb.unresolved_type when one of the sides of the operator is of the type duckdb.unresolved_type, for instance r['age'] + 10.
Once the query gets executed by DuckDB the actual type will be filled in by DuckDB. So, a query result will never contain a column that has duckdb.unresolved_type as its type. And generally you shouldn't even realize that this type even exists. So, if you get errors involving this type, please report an issue.
The duckdb.json type is used as arguments to DuckDB JSON functions. This type exists so that these functions can take values of json, jsonb and duckdb.unresolved_type.