Skip to content

Answer NULL where the MEOS function has no answer to give - #417

Merged
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:fix/binding-returns-null-where-meos-has-no-answer
Sep 27, 2026
Merged

estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:fix/binding-returns-null-where-meos-has-no-answer

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

A generated scalar binding returns SQL NULL where the MEOS function's
PostgreSQL wrapper does, as the catalog states it in shape.nullableResult: a
three-valued predicate answering below zero and a distance answering the
sentinel DBL_MAX. scalar_exec turns the stated guard into an ExecuteWithNulls
body marking the row invalid, as emit_geo_temporal marks its three-valued
predicates, and every by-value scalar emitter reads its executor, lambda and
return statement from it. A function whose catalog entry states no such guard
keeps the plain executor.

Witness. eDwithin(tgeompoint '[POINT(0 0)@2000-01-01, POINT(0 0)@2000-01-02)', tgeompoint '[POINT(0 0)@2000-01-02, POINT(0 0)@2000-01-03]', 300.0) answers
NULL, where (r != 0) read the -1 of two trips sharing no time as true, and
nearestApproachDistance of the same two trips answers NULL rather than
1.7976931348623157e+308. 064_tpoint_distance gains the two queries.

Measured. Regenerated against the catalog at the recorded MEOS commit
90009a793a, the surface holds the same 1870 bodies and 6680 registrations; 130
bodies change, each gaining its guard, and every one of the 207 emitted
functions whose catalog entry states if (result < 0) or
if (result == DBL_MAX) returns NULL on it. Over the 4781 candidate pairs of
one day of AIS trips in a 210 km2 belt, eDwithin at 300 m and a nearest
approach under 300 m disagreed on 218 pairs sharing no time, all read true by
eDwithin, and agree on every pair with the change. The 107 test files pass,
3053 assertions.

Why. A binding answering a value where MobilityDB answers NULL changes the
result of a query, and a benchmark written against the MobilityDB surface
counts 188 vessel pairs within 300 m where there are 182.

A generated scalar binding returns SQL NULL where the MEOS function's
PostgreSQL wrapper does, as the catalog states it in shape.nullableResult: a
three-valued predicate answering below zero and a distance answering the
sentinel DBL_MAX. scalar_exec turns the stated guard into an ExecuteWithNulls
body marking the row invalid, as emit_geo_temporal marks its three-valued
predicates, and every by-value scalar emitter reads its executor, lambda and
return statement from it. A function whose catalog entry states no such guard
keeps the plain executor.

Witness. `eDwithin(tgeompoint '[POINT(0 0)@2000-01-01, POINT(0 0)@2000-01-02)',
tgeompoint '[POINT(0 0)@2000-01-02, POINT(0 0)@2000-01-03]', 300.0)` answers
NULL, where `(r != 0)` read the -1 of two trips sharing no time as true, and
`nearestApproachDistance` of the same two trips answers NULL rather than
1.7976931348623157e+308. 064_tpoint_distance gains the two queries.

Measured. Regenerated against the catalog at the recorded MEOS commit
90009a793a, the surface holds the same 1870 bodies and 6680 registrations; 130
bodies change, each gaining its guard, and every one of the 207 emitted
functions whose catalog entry states `if (result < 0)` or
`if (result == DBL_MAX)` returns NULL on it. Over the 4781 candidate pairs of
one day of AIS trips in a 210 km2 belt, eDwithin at 300 m and a nearest
approach under 300 m disagreed on 218 pairs sharing no time, all read true by
eDwithin, and agree on every pair with the change. The 107 test files pass,
3053 assertions.

Why. A binding answering a value where MobilityDB answers NULL changes the
result of a query, and a benchmark written against the MobilityDB surface
counts 188 vessel pairs within 300 m where there are 182.
@estebanzimanyi
estebanzimanyi merged commit 9a64c53 into MobilityDB:main Sep 27, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant