Surfaced while assessing the feasibility of adding cross-binding geodetic temporal spatial-relationship test coverage to MobilityDuck (analog of PyMEOS's TestTGeogPointTemporalSpatialOperations). The conclusion is that the gap is not test-coverage and not addressable with test additions alone — it is an extension-runtime-stability issue documented in MobilityDuck itself.
Documented evidence in this repo
src/geo/stbox_functions.cpp (lines 23–26 and 1146):
MEOS stbox_area() can SIGSEGV on geodetic boxes (3D / PolyhedralSurface path). For geodetic footprints use spherical rectangle area (WGS84 sphere); avoids MEOS geog_in / geog_area faults.
closely enough for tests; avoids MEOS geog_in / geog_area which can SIGSEGV in this extension.
A C++ Spherical_lonlat_rect_area_m2 is in place as a deliberate sidestep of the MEOS geography path inside the loaded extension.
Structural consequences
| Step |
State |
GeoTypes::GEOMETRY() exists |
✅ used for the geo-argument side of all spatial-rel UDFs |
GeoTypes::GEOGRAPHY() exists |
❌ no such LogicalType |
spatial-rel UDFs register {TGEOGPOINT, GEOGRAPHY} overloads |
❌ only {TGEOGPOINT, GEOMETRY}, which MEOS rejects via ensure_same_geodetic_tspatial_geo |
tgeogpoint parity tests cover tDwithin / tIntersects / tDisjoint / tTouches |
❌ 042_tgeogpoint_parity.test has zero such queries — the absence is principled given the above |
So the temporal type tgeogpoint is registered and round-trips through IO, but invoking a spatial relationship on it against a static geo argument is structurally unreachable today because the binding has no geodetic static type to pair with it, and adding one would re-enter the documented geog_in SIGSEGV path.
Plausible root causes (each diagnosable)
- PROJ initialization missing in the DuckDB-extension load path.
geog_in uses PROJ for SRID transforms; standalone MEOS initialises PROJ via meos_initialize, but the in-extension MEOSLifecycle / equivalent may not configure PROJ search paths the way standalone does. (PROJ_DATA env-var is set in the standalone test harness but may not propagate into the loaded extension's process.)
- Allocator mismatch. Some MEOS geography helpers expected to be called inside a PostgreSQL memory context (palloc); MobilityDuck's extension context is plain malloc/free, and a
palloc cousin used by geog_in (or a lwgeom_* helper it calls) may dereference an uninitialised memory context.
*_meos.c linkage. geog_in may have a path defined in a meos/src/geo/*_meos.c file that is excluded from the PostgreSQL-extension build (the same class of issue as MobilityDB#1088's tgeo_from_base_temp — libmeos-only constructors), causing a deferred undefined-symbol or partial-link failure that manifests as a runtime crash rather than a load-time error.
- Thread-safety. DuckDB is multithreaded; MobilityDB#815 made MEOS thread-safe, but PROJ's
PJ_CONTEXT is not implicitly per-thread — a shared PROJ context can crash under concurrent geog_in calls.
Dependency-ordered path to unblock geodetic spatial-rel parity in MobilityDuck
- Root-cause and fix the
geog_in / geog_area SIGSEGV inside the DuckDB extension (issue this one).
- Add
GeoTypes::GEOGRAPHY() LogicalType + IO mirroring GEOMETRY().
- Register
{TGEOGPOINT, GEOGRAPHY} and {GEOGRAPHY, TGEOGPOINT} overloads for tDwithin / tIntersects / tDisjoint / tTouches.
- Add the geodetic spatial-rel parity test cases (the PyMEOS / GoMEOS / JMEOS fixtures already encode the geodetically-correct expected values that mirror MobilityDB#1088).
Until step 1 lands, geodetic spatial-rel testing in MobilityDuck is structurally unreachable. The cross-binding test-coverage parity work tracked in PyMEOS-side analyses correctly stops here for MobilityDuck.
Filed as the precise predicate for MobilityDB#1088's downstream propagation in MobilityDuck.
Surfaced while assessing the feasibility of adding cross-binding geodetic temporal spatial-relationship test coverage to MobilityDuck (analog of PyMEOS's
TestTGeogPointTemporalSpatialOperations). The conclusion is that the gap is not test-coverage and not addressable with test additions alone — it is an extension-runtime-stability issue documented in MobilityDuck itself.Documented evidence in this repo
src/geo/stbox_functions.cpp(lines 23–26 and 1146):A C++
Spherical_lonlat_rect_area_m2is in place as a deliberate sidestep of the MEOS geography path inside the loaded extension.Structural consequences
GeoTypes::GEOMETRY()existsGeoTypes::GEOGRAPHY()exists{TGEOGPOINT, GEOGRAPHY}overloads{TGEOGPOINT, GEOMETRY}, which MEOS rejects viaensure_same_geodetic_tspatial_geotgeogpointparity tests covertDwithin/tIntersects/tDisjoint/tTouches042_tgeogpoint_parity.testhas zero such queries — the absence is principled given the aboveSo the temporal type
tgeogpointis registered and round-trips through IO, but invoking a spatial relationship on it against a static geo argument is structurally unreachable today because the binding has no geodetic static type to pair with it, and adding one would re-enter the documentedgeog_inSIGSEGV path.Plausible root causes (each diagnosable)
geog_inuses PROJ for SRID transforms; standalone MEOS initialises PROJ viameos_initialize, but the in-extensionMEOSLifecycle/ equivalent may not configure PROJ search paths the way standalone does. (PROJ_DATAenv-var is set in the standalone test harness but may not propagate into the loaded extension's process.)palloccousin used bygeog_in(or alwgeom_*helper it calls) may dereference an uninitialised memory context.*_meos.clinkage.geog_inmay have a path defined in ameos/src/geo/*_meos.cfile that is excluded from the PostgreSQL-extension build (the same class of issue as MobilityDB#1088'stgeo_from_base_temp— libmeos-only constructors), causing a deferred undefined-symbol or partial-link failure that manifests as a runtime crash rather than a load-time error.PJ_CONTEXTis not implicitly per-thread — a shared PROJ context can crash under concurrentgeog_incalls.Dependency-ordered path to unblock geodetic spatial-rel parity in MobilityDuck
geog_in/geog_areaSIGSEGV inside the DuckDB extension (issue this one).GeoTypes::GEOGRAPHY()LogicalType + IO mirroringGEOMETRY().{TGEOGPOINT, GEOGRAPHY}and{GEOGRAPHY, TGEOGPOINT}overloads fortDwithin/tIntersects/tDisjoint/tTouches.Until step 1 lands, geodetic spatial-rel testing in MobilityDuck is structurally unreachable. The cross-binding test-coverage parity work tracked in PyMEOS-side analyses correctly stops here for MobilityDuck.
Filed as the precise predicate for MobilityDB#1088's downstream propagation in MobilityDuck.