Chapter 20. Portable Named-Function Dialect

Every MobilityDB operator is also callable as a bare named function. A query written with named functions only, using no operator symbols, is portable: the same SQL runs unchanged across the MobilityDB ecosystem — the database engines MobilityDB (PostgreSQL), MobilityDuck (DuckDB) and MobilitySpark (Apache Spark), and the streaming engines — several of which cannot register PostgreSQL operator symbols. Each named alias reuses the operator's own implementation, so it returns exactly the same result as the operator.

This chapter is the canonical, ecosystem-wide reference for that mapping. An engine that does not accept a given operator can look it up here and use the function form instead. For example, DuckDB does not accept any operator containing # (it reserves # for positional column references), so on MobilityDuck the temporal comparisons (#=, …) are written tEq, … and the time-position tests (<<#, #>>, &<#, #&>) are written before, after, overbefore, overafter, while the operators it does accept may be used directly.

The spatial-relationship functions (eIntersects, aIntersects, eTouches, eDwithin, …) and the restriction functions (atTime, atGeometry, atValue, …) are only ever named functions (they have no operator). The B-tree ordering comparator is likewise the named function cmp(a, b), which returns -1, 0 or 1 and has no operator. Every operator maps to a bare name as follows; for the arithmetic and set-theoretic operators the function name carries the operand's type-family prefix (set, span or spanset, and t for temporal numbers).

CategoryOperatorPortable function
Topology&&overlaps(a, b)
 @>contains(a, b)
 <@contained(a, b)
 -|-adjacent(a, b)
Time position<<#before(a, b)
 #>>after(a, b)
 &<#overbefore(a, b)
 #&>overafter(a, b)
Space, X axis<<left(a, b)
 >>right(a, b)
 &<overleft(a, b)
 &>overright(a, b)
Space, Y axis<<|below(a, b)
 |>>above(a, b)
 &<|overbelow(a, b)
 |&>overabove(a, b)
Space, Z axis<</front(a, b)
 />>back(a, b)
 &</overfront(a, b)
 /&>overback(a, b)
Temporal comparison#=tEq(a, b)
 #<>tNe(a, b)
 #<tLt(a, b)
 #<=tLe(a, b)
 #>tGt(a, b)
 #>=tGe(a, b)
Distance<->tDistance(a, b)
 |=|nearestApproachDistance(a, b)
Same~=same(a, b)
Traditional comparison=eq(a, b)
 <>ne(a, b)
 <lt(a, b)
 <=le(a, b)
 >gt(a, b)
 >=ge(a, b)
Ever comparison?=eEq(a, b)
 ?<>eNe(a, b)
 ?<eLt(a, b)
 ?<=eLe(a, b)
 ?>eGt(a, b)
 ?>=eGe(a, b)
Always comparison%=aEq(a, b)
 %<>aNe(a, b)
 %<aLt(a, b)
 %<=aLe(a, b)
 %>aGt(a, b)
 %>=aGe(a, b)
Arithmetic (temporal numbers)+tAdd(a, b)
 -tSub(a, b)
 *tMul(a, b)
 /tDiv(a, b)
Union (set / span / span set)+setUnion / spanUnion / spansetUnion (a, b)
Intersection (set / span / span set)*setIntersection / spanIntersection / spansetIntersection (a, b)
Difference (set / span / span set)-setMinus / spanMinus / spansetMinus (a, b)

For example, the bounding-box overlap t1.trip && t2.trip is written portably as overlaps(t1.trip, t2.trip), and the temporal-before test p1.period <<# p2.period as before(p1.period, p2.period).

Aggregate functions follow the same principle, and are listed in their own table below so that an engine can look up the machinery it needs without hunting through the prose. A SQL aggregate is assembled from up to three PostgreSQL machinery functions, each exposed under a canonical name built from the aggregate name and its role: a transition function <aggregate>Transition (always present), a combine function <aggregate>Combine used for parallel aggregation, and a final function <aggregate>Final. The combine and final roles are each optional: an aggregate whose transition state is already its result has no final function (for example extent and minDistance), and an aggregate that does not support partial aggregation has no combine function (for example the append aggregates). The roles stay distinct and uniformly named so that every binding can reconstruct the aggregate from the catalog. The following table lists every aggregate and its machinery functions; a dash (—) marks a role the aggregate does not define.

CategoryTransitionCombineFinal
CounttCountTransitiontCountCombinetCountFinal
 wCountTransitionwCountCombinewCountFinal
SumtSumTransitiontSumCombinetSumFinal
 wSumTransitionwSumCombinewSumFinal
AveragetAvgTransitiontAvgCombinetAvgFinal
 wAvgTransitionwAvgCombinewAvgFinal
Minimum / maximumtMinTransitiontMinCombinetMinFinal
 tMaxTransitiontMaxCombinetMaxFinal
 wMinTransitionwMinCombinewMinFinal
 wMaxTransitionwMaxCombinewMaxFinal
 tMinAggTransitiontMinAggCombinetMinAggFinal
 tMaxAggTransitiontMaxAggCombinetMaxAggFinal
BooleantAndTransitiontAndCombinetAndFinal
 tOrTransitiontOrCombinetOrFinal
CentroidtCentroidTransitiontCentroidCombinetCentroidFinal
Point cloudtnpointsTransitiontnpointsCombinetnpointsFinal
 tdensityTransitiontdensityCombinetdensityFinal
Bounding boxextentTransitionextentCombine
DistanceminDistanceTransitionminDistanceCombine
UnionsetUnionTransitionsetUnionCombinesetUnionFinal
 spanUnionTransitionspanUnionCombinespanUnionFinal
 spansetUnionTransitionspansetUnionCombinespansetUnionFinal
MergemergeTransitionmergeCombinemergeFinal
 mergeAggTransitionmergeAggCombinemergeAggFinal
AppendappendInstantTransitionappendInstantFinal
 appendInstantAggTransitionappendInstantAggFinal
 appendSequenceTransitionappendSequenceFinal
 appendSequenceAggTransitionappendSequenceAggFinal