Skip to content

Geography support is blocked at the extension runtime: geog_in / geog_area SIGSEGV in the loaded DuckDB extension #157

@estebanzimanyi

Description

@estebanzimanyi

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

  1. Root-cause and fix the geog_in / geog_area SIGSEGV inside the DuckDB extension (issue this one).
  2. Add GeoTypes::GEOGRAPHY() LogicalType + IO mirroring GEOMETRY().
  3. Register {TGEOGPOINT, GEOGRAPHY} and {GEOGRAPHY, TGEOGPOINT} overloads for tDwithin / tIntersects / tDisjoint / tTouches.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions