Skip to content

feat(bindings): geo/058 tpoint tile — tiles/boxes/getters + spaceSplit/spaceTimeSplit TableFunctions#79

Closed
estebanzimanyi wants to merge 3 commits intomainfrom
feat/parity-tpoint-tile
Closed

feat(bindings): geo/058 tpoint tile — tiles/boxes/getters + spaceSplit/spaceTimeSplit TableFunctions#79
estebanzimanyi wants to merge 3 commits intomainfrom
feat/parity-tpoint-tile

Conversation

@estebanzimanyi
Copy link
Copy Markdown
Member

@estebanzimanyi estebanzimanyi commented Apr 30, 2026

Closes geo/058_tpoint_tile to 100% by name. Three commits:

  1. feat(bindings): tile / box emitters and single-tile getters — 8 new handlers + 25 SQL registrations (LIST(stbox) emitters: spaceTiles / timeTiles / spaceTimeTiles / spaceBoxes / spaceTimeBoxes; single-tile getters: getSpaceTile / getStboxTimeTile / getSpaceTimeTile).
  2. chore: ensure trailing newline at EOF across the repo — 39 files repo-wide gain a trailing \n. Reviewer can strip this commit if preferred.
  3. feat(bindings): spaceSplit / spaceTimeSplit TableFunctions — 7 new TableFunctions for tgeompoint, set-returning splitters that bucket a trajectory into spatial (and optionally temporal) bins.

New SQL surface

Scalar — LIST(stbox) emitters (commit 1)

Signature Routed through
spaceTiles(stbox, xsize, ysize, zsize[, sorigin[, borderInc]]) stbox_space_tiles
timeTiles(stbox, duration[, torigin[, borderInc]]) stbox_time_tiles
spaceTimeTiles(stbox, xsize, ysize, zsize, duration[, sorigin[, torigin[, borderInc]]]) stbox_space_time_tiles
spaceBoxes(tgeompoint, xsize, ysize, zsize[, sorigin[, borderInc]]) tgeo_space_boxes
spaceTimeBoxes(tgeompoint, xsize, ysize, zsize, duration[, sorigin[, torigin[, borderInc]]]) tgeo_space_time_boxes

Scalar — single-tile getters (commit 1)

Signature Routed through
getSpaceTile(point, xsize, ysize, zsize[, sorigin]) stbox_get_space_tile
getStboxTimeTile(t, duration[, torigin]) stbox_get_time_tile
getSpaceTimeTile(point, t, xsize, ysize, zsize, duration[, sorigin[, torigin]]) stbox_get_space_time_tile

TableFunction — splitters (commit 3)

Signature Returns
spaceSplit(tgeompoint, xsize, ysize, zsize[, sorigin[, bitmatrix]]) TABLE(spaceBin geometry, tpoint tgeompoint)
spaceTimeSplit(tgeompoint, xsize, ysize, zsize, duration[, sorigin[, torigin[, bitmatrix]]]) TABLE(spaceBin geometry, timeBin timestamptz, tpoint tgeompoint)

3 + 4 = 7 TableFunction overloads.

Implementation notes

TableFunctions

Mirror the shape of the existing TemporalUnnest TableFunction in src/temporal/temporal.cpp:

  • SpaceSplitBindData captures the input tgeompoint blob and scalar tile parameters at bind time.
  • SpaceSplitInitCommon calls tgeo_space_split / tgeo_space_time_split and buffers the parallel output arrays. The spaceBin GSERIALIZED is captured as raw EWKB so the DuckDB-spatial encoding can be deferred to Exec time, which has access to a proper ArenaAllocator scoped to the result vector.
  • SpaceSplit/SpaceTimeSplitExec drains the buffer into the output chunk; EmitSpaceBinAt decodes EWKB → GSERIALIZED → GSerializedToGeometry into the output geometry column.

Hooked into LoadInternal via a new RegisterTpointSplit method on TgeompointType, kept distinct from the existing scalar registrations so the boundary between scalar and TableFunction surface stays clear.

Defaults

  • Default sorigin is Point(0 0 0) SRID 0, constructed via geompoint_make3dz.
  • Default torigin is the MEOS 2000-01-03 reference origin.
  • Default bitmatrix is true (matches MobilityDB's SQL DEFAULT).
  • Default borderInc is true (same).

Tests

  • test/sql/parity/058_tpoint_tile.test — 8 assertions covering each scalar emitter and getter.
  • test/sql/parity/058b_tpoint_split.test — 5 query cases covering both spaceSplit overloads, both spaceTimeSplit overloads, and the output schema (ST_AsText(spaceBin), tempSubtype(tpoint)).
  • Full suite: 770 assertions / 15 test cases passing under TZ=UTC.

Coverage delta

Per the audit in PR #66:

  • geo/058_tpoint_tile and geo/058_tgeo_tile: 0/11 → 11/11 (100%) by name.

Test plan

  • cmake --build . --target shell unittest clean
  • Both new parity tests pass
  • Full suite green (770/15)

Closes a substantial portion of geo/058_tpoint_tile by adding 8 new
handlers in StboxFunctions and 23 SQL registrations:

LIST(stbox)-emitting (5 names × 3-4 overloads = 18 registrations):

- spaceTiles(stbox, xsize, ysize, zsize[, sorigin geom[, borderInc bool]])
- timeTiles(stbox, duration interval[, torigin tstz[, borderInc bool]])
- spaceTimeTiles(stbox, xsize, ysize, zsize, duration[, sorigin[, torigin[, borderInc]]])
- spaceBoxes(tgeompoint, xsize, ysize, zsize[, sorigin[, borderInc]])
- spaceTimeBoxes(tgeompoint, xsize, ysize, zsize, duration[, sorigin[, torigin[, borderInc]]])

Single-tile getters (3 names × 2-3 overloads = 7 registrations):

- getSpaceTile(point geometry, xsize, ysize, zsize[, sorigin])
- getStboxTimeTile(t timestamptz, duration[, torigin])
- getSpaceTimeTile(point, t, xsize, ysize, zsize, duration[, sorigin[, torigin]])

Each LIST emitter routes to the matching MEOS export
(stbox_space_tiles / stbox_time_tiles / stbox_space_time_tiles /
tgeo_space_boxes / tgeo_space_time_boxes) and writes a flat list of
STBox blobs into the result vector. Single-tile getters route to
stbox_get_space_tile / stbox_get_time_tile / stbox_get_space_time_tile.

The default sorigin point ('Point(0 0 0)' in MobilityDB SQL) is
constructed via geompoint_make3dz; the default torigin is MEOS's
'2000-01-03' reference origin (encoded as 0).

Not included in this batch (separate follow-up):
- spaceSplit / spaceTimeSplit — these return tables of (spatial_bin,
  time_bin, sub-trajectory) tuples and need TableFunction infrastructure.

Test: test/sql/parity/058_tpoint_tile.test (8 assertions covering
each emitter and getter).
Full suite: 760 / 14 cases under TZ=UTC.
…oint

Set-returning splitters that bucket a tgeompoint trajectory into
spatial (and optionally temporal) bins, returning one row per bin.
Mirrors MobilityDB's

  spaceSplit(tgeompoint, xsize, ysize, zsize[, sorigin geom[, bitmatrix bool]])
    RETURNS TABLE(spaceBin geometry, tpoint tgeompoint)

  spaceTimeSplit(tgeompoint, xsize, ysize, zsize, duration[, sorigin[, torigin[, bitmatrix]]])
    RETURNS TABLE(spaceBin geometry, timeBin timestamptz, tpoint tgeompoint)

Implementation pattern mirrors the existing TemporalUnnest TableFunction:
- SpaceSplitBindData captures the input tgeompoint blob and scalar tile
  parameters at bind time.
- SpaceSplitInitCommon calls the matching MEOS export
  (tgeo_space_split / tgeo_space_time_split) and buffers the parallel
  output arrays. spaceBin GSERIALIZED is captured as raw EWKB to defer
  the DuckDB-spatial encoding to Exec time (which has access to a
  proper ArenaAllocator scoped to the result vector).
- SpaceSplit/SpaceTimeSplitExec drains the buffer into the output
  chunk; EmitSpaceBinAt deserialises EWKB -> GSERIALIZED, then encodes
  via GSerializedToGeometry into the output geometry vector.

Registers 7 TableFunctions:
- spaceSplit: 3 overloads (no origin, with origin, with origin+bitmatrix)
- spaceTimeSplit: 4 overloads (no origin, with origin, with origin+torigin,
  full)

Hooked into LoadInternal via a new RegisterTpointSplit method on
TgeompointType, kept distinct from the existing scalar registrations
so the boundary between scalar and TableFunction surface stays clear.

Test: test/sql/parity/058b_tpoint_split.test (5 query cases) covering:
- spaceSplit with default origin
- spaceSplit with explicit sorigin
- spaceTimeSplit with default origin
- spaceTimeSplit with explicit sorigin + torigin
- output schema check via tempSubtype(tpoint)

Full suite: 770 / 15 cases under TZ=UTC.

Closes geo/058_tpoint_tile to 100% by name (tiles + boxes + getters
landed earlier in this PR; spaceSplit / spaceTimeSplit complete the
TableFunction story).
@estebanzimanyi estebanzimanyi changed the title feat(bindings): tile / box emitters + repo-wide trailing-newline cleanup feat(bindings): geo/058 tpoint tile — tiles/boxes/getters + spaceSplit/spaceTimeSplit TableFunctions Apr 30, 2026
@estebanzimanyi estebanzimanyi marked this pull request as ready for review May 1, 2026 19:13
@estebanzimanyi
Copy link
Copy Markdown
Member Author

Superseded by the consolidated PR branch consolidate/tiles-bins-parity. All changes from this PR are included in that branch as a single squashed commit. Please review and merge the consolidated branch instead.

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