duckdb / duckdb/duckdb-spatial

`ST_Dump` inconsistency for EMPTY geometries

Open
#846 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
708
Forks
96
Avg merge
1d 21h
Merged PRs (30d)
5

Description

## Affected Versions

- **DuckDB**: v1.5.5-dev150 (development build)
- **Spatial**: debug build from `duckdb_spatial/` (GEOS-backed)

## Reproducible Script

```python
import duckdb

conn = duckdb.connect(":memory:", config={"allow_unsigned_extensions": True})
conn.execute("INSTALL spatial;")
conn.execute("LOAD spatial;")

# === Bug 1: ST_Dump returns 1 row for singleton EMPTY geometries ===
# ST_NumGeometries returns 0, but len(ST_Dump(...)) returns 1

for wkt in ["POINT EMPTY", "LINESTRING EMPTY", "POLYGON EMPTY"]:
sql = f"""
SELECT
ST_NumGeometries(ST_GeomFromText('{wkt}')) AS ng,
len(ST_Dump(ST_GeomFromText('{wkt}'))) AS dump_len,
ST_IsEmpty(ST_GeomFromText('{wkt}')) AS empty
"""
r = conn.execute(sql).fetchone()
ok = "" if r[0] == r[1] else " <<< BUG"
print(f"{wkt:20} NumGeom={r[0]} DumpLen={r[1]} IsEmpty={r[2]}{ok}")

# === Bug 2: ST_NumGeometries counts typed-empty GC children ===
# IsEmpty=True and NumGeom>0, but Dump returns 0

for wkt in [
"GEOMETRYCOLLECTION(MULTILINESTRING EMPTY)",
"GEOMETRYCOLLECTION(MULTIPOLYGON EMPTY)",
"GEOMETRYCOLLECTION EMPTY",
]:
sql = f"""
SELECT
ST_NumGeometries(ST_GeomFromText('{wkt}')) AS ng,
len(ST_Dump(ST_GeomFromText('{wkt}'))) AS dump_len,
ST_IsEmpty(ST_GeomFromText('{wkt}')) AS empty
"""
r = conn.execute(sql).fetchone()
ok = "" if r[0] == r[1] else " <<< BUG"
print(f"{wkt:55} NumGeom={r[0]} DumpLen={r[1]} IsEmpty={r[2]}{ok}")
```

### Actual Output

```
POINT EMPTY NumGeom=0 DumpLen=1 IsEmpty=True <<< BUG
LINESTRING EMPTY NumGeom=0 DumpLen=1 IsEmpty=True <<< BUG
POLYGON EMPTY NumGeom=0 DumpLen=1 IsEmpty=True <<< BUG
GEOMETRYCOLLECTION(MULTILINESTRING EMPTY) NumGeom=1 DumpLen=0 IsEmpty=True <<< BUG
GEOMETRYCOLLECTION(MULTIPOLYGON EMPTY) NumGeom=1 DumpLen=0 IsEmpty=True <<< BUG
GEOMETRYCOLLECTION EMPTY NumGeom=0 DumpLen=0 IsEmpty=True OK
```

### Expected Output (PostGIS 3.7 / GEOS 3.15 reference)

```
POINT EMPTY NumGeom=0 DumpLen=0 IsEmpty=True OK
LINESTRING EMPTY NumGeom=0 DumpLen=0 IsEmpty=True OK
POLYGON EMPTY NumGeom=0 DumpLen=0 IsEmpty=True OK
GEOMETRYCOLLECTION(MULTILINESTRING EMPTY) NumGeom=0 DumpLen=0 IsEmpty=True OK
GEOMETRYCOLLECTION(MULTIPOLYGON EMPTY) NumGeom=0 DumpLen=0 IsEmpty=True OK
GEOMETRYCOLLECTION EMPTY NumGeom=0 DumpLen=0 IsEmpty=True OK
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the spatial extension entry points for ST_Dump and ST_NumGeometries in duckdb_spatial/, then run the reproducible Python script against the listed EMPTY geometries. The work is done when ST_Dump and ST_NumGeometries agree for all cases and match the expected output shown in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.