Skip to content

bug: DuckDB backend: con.create_table / con.insert fails for geospatial columns with BLOB -> GEOMETRY cast (Ibis 12) #11999

Description

@samlalwani

What happened?

When writing an Ibis expression that contains a geospatial:geometry column to DuckDB, both:

con.create_table("name", expr, overwrite=True)
con.insert("name", expr)
fail with:

Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY)

This appears to come from generated SQL that applies ST_ASWKB("geometry"), producing a BLOB that DuckDB then tries to cast into a GEOMETRY column.

What did you expect to happen?
I expected both create_table and insert to write geospatial columns directly (or round-trip them safely) without requiring manual SQL workarounds.

reproducible example:

import ibis
import duckdb

print("ibis", ibis.__version__)
print("duckdb", duckdb.__version__)

con = ibis.duckdb.connect(extensions=["spatial"])

expr = con.sql("""
    SELECT
      1::INTEGER AS id,
      ST_Point(1.0, 2.0) AS geometry
""")

print("expr schema:", expr.schema())
# expr schema includes: geometry geospatial:geometry

# 1) Fails
con.create_table("tmp_geospatial_from_sql", expr, overwrite=True)

# 2) Also fails
con.create_table("tmp_insert_target", schema=expr.schema(), overwrite=True)
con.insert("tmp_insert_target", expr)

What version of ibis are you using?

ibis 12.0.0

What backend(s) are you using, if any?

duckdb 1.5.1 with spatial extension enabled

Relevant log output

raceback from con.create_table(...):

Traceback (most recent call last):
File "<stdin>", line 19, in <module>
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init_.py", line 236, in create_table
cur.execute(insert_stmt).fetchall()
~~~~~~~~~~~^^^^^^^^^^^^^
_duckdb.ConversionException: Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY) when casting from source column geometry

LINE 1: ...szpfbqbbxlc6wacexioe" ("id", "geometry") SELECT * REPLACE (ST_ASWKB("geometry") AS "geometry") FROM (SELECT CAST(1...
^

Traceback from con.insert(...):

Traceback (most recent call last):
File "<stdin>", line 20, in <module>
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\sql_init_.py", line 463, in insert
with self.safe_raw_sql(query):
~~~~~~~~~~~~~~~~~~^^^^^^^
File "C:\Users\sameer\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\contextlib.py", line 141, in enter
return next(self.gen)
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init.py", line 348, in safe_raw_sql
yield self.raw_sql(*args, **kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init.py", line 116, in raw_sql
return self.con.execute(query, **kwargs)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
_duckdb.ConversionException: Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY) when casting from source column geometry

LINE 1: ... INTO "tmp_insert_target" ("id", "geometry") SELECT * REPLACE (ST_ASWKB("geometry") AS "geometry") FROM (SELECT CAST(1...

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIncorrect behavior inside of ibis

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions