Skip to content

Bump GoMEOS to MEOS 1.4#3

Open
estebanzimanyi wants to merge 7 commits into
refactor/codegen-meos-idlfrom
bump/meos-1.4
Open

Bump GoMEOS to MEOS 1.4#3
estebanzimanyi wants to merge 7 commits into
refactor/codegen-meos-idlfrom
bump/meos-1.4

Conversation

@estebanzimanyi
Copy link
Copy Markdown
Member

Vendors the MEOS 1.4 IDL (3544 functions, +1149 over 1.3) on top of #2 and adds meos_cbuffer.h, meos_pose.h, and meos_rgeo.h to the codegen header list. Regenerates tools/_preview/ against the new catalog. Updates the hand-written wrappers in main_tpoint.go to match the MEOS 1.4 signatures: the tspatial-rel family (tcontains/tdisjoint/tdwithin/tintersects/ttouches) dropped the restr and atvalue parameters, and tpoint_at_geom/tpoint_minus_geom dropped the trailing z-span filter.

Vendor the MEOS 1.4 IDL (3544 functions, +1149 over 1.3) and the three
new public headers (meos_cbuffer.h, meos_pose.h, meos_rgeo.h) to
HEADER_FILES. Regenerate the tools/_preview/ wrappers against the new
catalog.

Update the hand-written wrappers in main_tpoint.go to match the MEOS
1.4 signatures: the tspatial-rel family (tcontains/tdisjoint/tdwithin/
tintersects/ttouches) dropped the restr/atvalue parameters and
tpoint_at_geom/tpoint_minus_geom dropped the trailing z-span filter.
estebanzimanyi and others added 4 commits May 14, 2026 15:36
The previous IDL was parsed from the MobilityDB source tree which
duplicates GSERIALIZED across build/postgis headers. Libclang
canonicalised the type to int * for ~400 geometry-bearing functions.
Regenerated against /usr/local/include and the codegen now emits
proper GSERIALIZED * wrappers.

TODO counts on the public surface dropped:
  meos_geo.h:          200 -> 0
  meos.h:              157 -> 10
  meos_internal.h:      22 -> 13
  meos_internal_geo.h:  12 -> 0
  meos_npoint.h:        15 -> 0

The remaining cbuffer/pose TODOs need shape metadata in MEOS-API for
the *_in/_out/_round families before they can be wrapped without
human intervention.
The MEOS 1.4 surface adds the cbuffer, pose, and rgeo temporal type
families.  Add them to WRAPPER_TYPES so the generator emits proper
*Cbuffer / *Pose / *Rgeo wrappers instead of leaving 277 TODO stubs.

TODO counts on the new headers drop to:
  meos_cbuffer.h: 105 -> 1
  meos_pose.h:     77 -> 2
  meos_rgeo.h:      1 -> 0

The three remaining (cbufferset_values, poseset_values, pose_orientation)
need shape metadata in MEOS-API before they can be wrapped without
hand-rolling the length-from-accessor pattern.
MEOS-API now carries arrayReturn metadata for cbufferset_values and
poseset_values, mirroring geoset_values. cbuffer TODO drops 1 -> 0;
pose TODO drops 2 -> 1 (only pose_orientation remains, which returns a
fixed-size 4-element quaternion that needs its own shape kind).
State that GoMEOS tracks MEOS 1.4 and that the wrappers are generated
from the MEOS-API meos-idl.json catalog, pointing at tools/README.md for
regeneration, and fix the MobilityDB link to the source repository.
@estebanzimanyi estebanzimanyi requested a review from Davichet-e May 15, 2026 05:30
@Davichet-e
Copy link
Copy Markdown
Member

I'll take a look after the #1 is merged

estebanzimanyi added a commit to estebanzimanyi/GoMEOS that referenced this pull request May 18, 2026
Add the canonical portable bare-name dialect (RFC #920) parity gate so
GoMEOS exposes the same operator -> bareName surface as every other
MobilityDB binding/engine, verified by construction across all six
in-scope user-facing type families.

Stacks on the MEOS 1.4 bump (PR MobilityDB#3, bump/meos-1.4): the IDL-driven
codegen there emits tools/_preview/*.go from tools/meos-idl.json (the
MEOS-API parser's JSON output), wrapping every operator's own backing C
function for temporal, geo, cbuffer, npoint, pose and rgeo.

- tools/portable-aliases.json: the 29-pair contract, vendored
  byte-identical from MEOS-API meta/portable-aliases.json (single source
  of truth); --idl prefers the catalog's folded-in copy once present.
- tools/portable_parity.py: audits the exposed CGO symbol set -- every
  C.<symbol>( in the hand-written root *.go AND the IDL-driven
  tools/_preview/*.go. A bare name is backed iff some referenced MEOS
  symbol == bareName or startswith(bareName + "_"), with the contract's
  verified explicitBacking (nearestApproachDistance <- nad_*). Reads
  JSON-derived artifacts only -- never parses meos.h.
- tools/parity/parity_test.go: pure-Go, no import "C" -- a
  language-independent mirror with an identical verdict that runs in CI
  with no libmeos/CGO toolchain.
- .github/workflows/portable-parity.yml: runs both gates on push/PR.
- tools/PORTABLE_ALIASES.md: documents the dialect and the gate.

Result: 29/29 bare names backed, 0 unbacked, all six in-scope families
covered (temporal, geo, cbuffer, npoint, pose, rgeo) -- 100% parity.
The gate hard-fails on any in-scope family that is present in the
surface but unbacked, or absent: cbuffer/npoint/pose/rgeo are full
user-facing types and are never excluded from the parity headline.
The pre-1.4 tdistance version bridge is now inert -- MEOS 1.4 provides
the canonical tdistance_* prefix.
MEOS 1.4 added an explicit `interp` argument to
temporal_append_tinstant (1.3 inferred it internally from the
temporal type's continuity). The 1.4 bump stopgapped it with a
hardcoded INTERP_NONE, so appending an instant to a TInstant of a
continuous type (TFloat / TGeomPoint / TGeogPoint / TCbuffer / ...)
promoted it with no interpolation instead of the LINEAR default the
type requires.

Restore the 1.3 semantics: derive the argument from the base type's
continuity via the MEOS catalog (LINEAR if the temptype supports
linear interpolation, STEP otherwise -- MEOS rejects LINEAR for
step-only types int/bool/text). MEOS renamed
temptype_continuous -> temptype_supports_linear in MobilityDB#1005;
the wrapper forward-declares the current name so it compiles
regardless of which name the vendored meos_catalog.h carries.

cgo cannot call temptype_supports_linear(MeosType type) directly
because `type` is a Go reserved word (the codegen flags it as an
unsupported-MeosType-param case in tools/_preview); a thin inline
wrapper in cast.h takes the Temporal* and reads its temptype inside C
to keep the MeosType-typed parameter out of the cgo boundary.

Mirrors PyMEOS fcbbce7 (the reference implementation of the same
MEOS-1.4 signature-change consequence). Verified: go build and go vet
clean against MobilityDB master's libmeos.
Mirrors PyMEOS's TestTGeogPointTemporalSpatialOperations
(tests/main/tgeogpoint_test.py, PyMEOS commit 74bd797): table-driven
tests of within_distance / intersects / disjoint on TGeogPointInst,
TGeogPointSeq (discrete + continuous) and TGeogPointSeqSet against
both a geometry argument and a temporal-point argument. Closes a
coverage-parity gap surfaced during the cross-binding geodetic-fixture
audit -- prior to this commit GoMEOS exercised TGeogPoint construction
and basic temporal ops but not these spatial relationships, so
regressions in either direction (geodetic working or breaking) were
silently unobserved.

Behaviour assumed by the assertions:

  * within_distance / intersects / disjoint with a static geometry
    argument: relies on MobilityDB#1088 (one geodetic distance kernel;
    intersects / disjoint derived from tdwithin(0)). Pre-#1088 the
    geodetic path returns NULL and CreateTemporal panics; a
    defer/recover runtime guard converts that panic into t.Skip so the
    suite stays green until #1088 lands in the MEOS this binding builds
    against. Post-#1088 the assertions activate automatically and catch
    regressions.

  * Pointwise (Instant / DiscreteSequence) expecteds use the
    geodesically-correct truths (distance POINT(1 1) -> POINT(2 2) is
    ~156876 m, far beyond the 2 m threshold). Continuous
    (Sequence / SequenceSet) expecteds reflect the current
    planar-approximate continuous turning point
    (tpointsegm_tdwithin_turnpt) tracked in MobilityDB#1087.

  * ttouches for geodetic input is deliberately not asserted: MEOS's
    default error handler terminates the process on "Only planar
    coordinates supported", which is not a catchable Go panic. The
    underlying ttouches geodetic gap (DE-9IM topological predicate, not
    tdwithin(0)) is tracked in MobilityDB#1087; the test can be enabled
    once GoMEOS installs a non-fatal MEOS error handler hook.

Subtest-per-concrete-type structure used because the typed generics
TXxxTPointGeo[TP TPoint] require one concrete TP per call. No
production-code changes. Verified locally: full new test set passes
against MobilityDB master + #1088 (11/11) -- the geodetic kernel
post-#1088 returns the expected results across Instant / Discrete /
Sequence / SequenceSet on both the geo-arg and tpoint-arg paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants