From fa2de5747e76f32283fec9460b4f4277333c18c1 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Fri, 29 May 2026 22:09:16 +0200 Subject: [PATCH 1/2] Pin MEOS with the wasm pg_config SIZEOF_LONG_LONG fix Adds the SIZEOF_LONG_LONG emission to the rendered pg_config.h so the DuckDB-Wasm (wasm32-emscripten / ILP32) build of MEOS no longer fails the pg_bitutils integer-width check. --- vcpkg_ports/meos/portfile.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcpkg_ports/meos/portfile.cmake b/vcpkg_ports/meos/portfile.cmake index 82619e3a..9aeff5d5 100644 --- a/vcpkg_ports/meos/portfile.cmake +++ b/vcpkg_ports/meos/portfile.cmake @@ -1,8 +1,8 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO estebanzimanyi/MobilityDB - REF a8178dc9d56d841d0eb5025a7e8717c8d25a1d0f - SHA512 030a144bb3247695702dd2de11f4c389ed28c6eb0186e6988a489e2b00e9801179ba8f27bcbcd81ae89e398a7277ed7f9ff7058dbf15f5db322ae4644365c560 + REF 3db47f887c61f049a6a03db55c48bedf6d10eee4 + SHA512 b73123bca036813c43937f90f0d0ce45af5cb9e39d6a597304199d21ae854212319a3a7b58ecd075eb5678d89d6d5990b9faf63dd29bd8c9a4e2ed83282b94c5 ) vcpkg_replace_string( From 4240d50c5105c81a66a5020063c673b481b2a392 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 20 May 2026 16:58:36 +0200 Subject: [PATCH 2/2] cleanup(geo): retire stale Spherical_lonlat workaround for geodetic stbox_area / stbox_to_geo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Spherical_lonlat_rect_area_m2 / Geodetic_stbox_footprint_area / Stbox_geodetic_xy_copy helpers were workarounds for two MEOS bugs that no longer exist on the pinned MEOS-1.4 integration tip: - geog_in WKT fall-through SIGSEGV — FIXED upstream in MobilityDB PR #1090 (closes #1089). - stbox_area / stbox_to_geo SIGSEGV on 3D geodetic boxes — verified NOT-a-current-bug across multiple direct probes: stbox_area(GEODSTBOX ZT(((1,2,3),(4,5,6)),[2000-01-01,2000-01-02])) returns 110593375170.3 cleanly on the integration MEOS. Replace the two-branch workaround in Stbox_area with a direct stbox_area call, drop the manual Z-strip in Stbox_expand_space (MEOS stbox_to_geo already projects 3D geodetic boxes to a 2D POLYGON with Z=0 internally), and re-enable the previously commented test for the GEODSTBOX ZT area case plus two new tests for X and Z geodetic shapes. Also fix the existing error-sentinel check on Stbox_area: MEOS stbox_area returns -1.0 on error (null box or no X dimension), not DBL_MAX (an artifact of the spherical-approximation workaround path). Stacks on PR #164 (vcpkg pin bump to MEOS-1.4-integration). --- src/geo/stbox_functions.cpp | 50 +++---------------------------------- test/sql/stbox.test | 19 ++++++++++---- 2 files changed, 18 insertions(+), 51 deletions(-) diff --git a/src/geo/stbox_functions.cpp b/src/geo/stbox_functions.cpp index b5398f02..37dd9924 100644 --- a/src/geo/stbox_functions.cpp +++ b/src/geo/stbox_functions.cpp @@ -4,13 +4,11 @@ #include "geo/stbox_functions.hpp" #include "time_util.hpp" #include "geo_util.hpp" -#include #include "duckdb/common/exception.hpp" #include "duckdb/common/vector.hpp" #include "duckdb/common/typedefs.hpp" -#include #include #include "spatial/spatial_types.hpp" @@ -20,36 +18,6 @@ namespace duckdb { namespace { -/* 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. */ -/* Sphere zone area between two meridians and parallels (m^2). Matches MEOS/PostGIS sphere model - * closely enough for tests; avoids MEOS geog_in/geog_area which can SIGSEGV in this extension. */ -inline double Spherical_lonlat_rect_area_m2(double xmin, double ymin, double xmax, double ymax, - bool use_spheroid) { - (void)use_spheroid; - constexpr double DEG_TO_RAD = M_PI / 180.0; - /* WGS84 semi-major axis (m); MEOS geog_area on sphere uses ~this for spheroid=false path. */ - constexpr double R = 6378137.0; - const double lam1 = xmin * DEG_TO_RAD; - const double lam2 = xmax * DEG_TO_RAD; - const double phi1 = ymin * DEG_TO_RAD; - const double phi2 = ymax * DEG_TO_RAD; - return R * R * (lam2 - lam1) * (std::sin(phi2) - std::sin(phi1)); -} - -inline double Geodetic_stbox_footprint_area(const STBox *box, bool use_spheroid) { - return Spherical_lonlat_rect_area_m2(box->xmin, box->ymin, box->xmax, box->ymax, use_spheroid); -} - -/* For stbox_to_geo: 2D geodetic box via MEOS constructor (no Z dimension in output geometry). */ -inline STBox *Stbox_geodetic_xy_copy(const STBox *box) { - if (!stbox_isgeodetic(box) || !stbox_hasz(box)) { - return nullptr; - } - return stbox_make(stbox_hasx(box), false, true, box->srid, box->xmin, box->xmax, box->ymin, box->ymax, - 0.0, 0.0, stbox_hast(box) ? &box->period : nullptr); -} - inline void Stbox_normalize_geodetic_srid(STBox *box) { if ((stbox_isgeodetic(box) || MEOS_FLAGS_GET_GEODETIC(box->flags)) && box->srid == 0) { box->srid = 4326; @@ -497,11 +465,8 @@ bool StboxFunctions::Geo_to_stbox_cast(Vector &source, Vector &result, idx_t cou throw InternalException("Failure in Stbox_expand_space: unable to cast binary to stbox"); } - STBox *flat = Stbox_geodetic_xy_copy(stbox); - STBox *geo_src = flat ? flat : stbox; - GSERIALIZED *gs = stbox_to_geo(geo_src); + GSERIALIZED *gs = stbox_to_geo(stbox); if (!gs) { - free(flat); free(stbox); throw InvalidInputException("Failed to convert stbox to geometry"); } @@ -510,7 +475,6 @@ bool StboxFunctions::Geo_to_stbox_cast(Vector &source, Vector &result, idx_t cou string_t stored_result = StringVector::AddStringOrBlob(result, geometry_blob); free(gs); - free(flat); free(stbox); return stored_result; } @@ -1142,16 +1106,10 @@ void StboxFunctions::Stbox_area(DataChunk &args, ExpressionState &state, Vector throw InternalException("Failure in Stbox_area: unable to cast binary to stbox"); } bool spheroid = true; // default value, TODO: handle argument - double ret; - /* MEOS stbox_area() can SIGSEGV on geodetic boxes; use spherical lon/lat footprint. */ - const bool geodetic = stbox_isgeodetic(stbox) || MEOS_FLAGS_GET_GEODETIC(stbox->flags); - if (geodetic) { - ret = Geodetic_stbox_footprint_area(stbox, spheroid); - } else { - ret = stbox_area(stbox, spheroid); - } + double ret = stbox_area(stbox, spheroid); free(stbox); - if (ret == DBL_MAX) { + /* MEOS stbox_area returns -1.0 on error (null box or no X dimension). */ + if (ret < 0) { mask.SetInvalid(idx); return double(); } diff --git a/test/sql/stbox.test b/test/sql/stbox.test index 87b4dcc7..64291fd7 100644 --- a/test/sql/stbox.test +++ b/test/sql/stbox.test @@ -85,11 +85,20 @@ SELECT area(stbox 'STBOX ZT(((1.0,2.0,3.0),(4.0,5.0,6.0)),[2000-01-01,2000-01-02 ---- 9 -# TODO: re-enable when MEOS stbox_area no longer SIGSEGVs on GEODSTBOX ZT (PolyhedralSurface path). -# query I -# SELECT round(area(stbox 'GEODSTBOX ZT(((1.0,2.0,3.0),(4.0,5.0,6.0)),[2000-01-01,2000-01-02])'), 1); -# ---- -# 110593375170.3 +query I +SELECT round(area(stbox 'GEODSTBOX ZT(((1.0,2.0,3.0),(4.0,5.0,6.0)),[2000-01-01,2000-01-02])'), 1); +---- +110593375170.3 + +query I +SELECT round(area(stbox 'GEODSTBOX X((1.0,2.0),(3.0,4.0))'), 1); +---- +49173168695.2 + +query I +SELECT round(area(stbox 'GEODSTBOX Z((1.0,2.0,3.0),(4.0,5.0,6.0))'), 1); +---- +110593375170.3 query I SELECT expandSpace(stbox 'STBOX XT(((1.0,2.0),(1.0,2.0)),[2000-01-01,2000-01-01])', 2.0);