Skip to content

Generate the base-value scalar accessors - #229

Open
estebanzimanyi wants to merge 3 commits into
mainfrom
feat/duck-baseval-scalar-accessors
Open

Generate the base-value scalar accessors#229
estebanzimanyi wants to merge 3 commits into
mainfrom
feat/duck-baseval-scalar-accessors

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

Generates the base-value scalar accessors from the MEOS catalog. A base
value (cbuffer / npoint / nsegment) goes in, a scalar comes out — the last
piece of the base-value surface that the generator did not yet cover.

Generator

Adds a (BaseValue*)->by-value scalar shape (shape_baseval_scalar +
emit_baseval_scalar) and a self-contained dispatch arm. The value is
marshalled via BlobTo<Base> (the existing PTR_IN map) and freed; the UDF
registers over the base accessor type. Base values are not temporal or geo,
so no other shape emits them — the arm sits before the temporal shape chain
and is fully self-contained.

Emitted surface

For the registered base families:

  • cbuffer: radius, SRID, hash (native-unsigned UINTEGER, matching the
    temporal / span / set / box hashes)
  • npoint: route, position, SRID
  • nsegment: route, startPosition, endPosition, SRID

Pure addition — there are no hand registrations to retire. Pose accessors
follow automatically once the pose type is registered.

Reserved word

position is a DuckDB reserved word: the function registers correctly but a
bare position(x) call fails to parse, so it is called double-quoted
("position"(x)) — the same reserved-form limitation the hash-operator names
already have. The generator emits the canonical catalog name unchanged.

Tests

Adds test/sql/parity/091_baseval_scalar_accessors.test covering radius /
SRID / hash / route / position / startPosition / endPosition. The committed
src/generated file is the generator's output for the current catalog.

nhungoc1508 and others added 3 commits July 22, 2026 21:40
…ical

Regenerates the generated UDF surface from MobilityDB master (which brings in
the generic temporal_hash surface). The MEOS-API catalog now renders the uint32
canonical type as `unsigned int` (it was `uint32_t`); key the scalar type maps
on it so the *_hash functions keep registering instead of being dropped.

uint32 hashes map to DuckDB's native `UINTEGER`, not a signed `INTEGER` — a hash
>= 2**31 is out of range for INT32 and DuckDB range-checks the cast rather than
bit-reinterpreting the way PostgreSQL/C do; DuckDB has real unsigned SQL types,
so `UINTEGER` is the faithful representation.
Add the network-point temporal family (npoint / nsegment / tnpoint) to the
MobilityDuck generated surface as the 2D-planar twin of cbuffer. Both inherit
Spatial<T> and are non-geodetic; the only difference is that npoint carries no
SRID or geometry of its own — a route identifier is resolved against a fixed
`ways` network (Npoint(1,0.5) vs Cbuffer(Point(1 1),1)).

- src/npoint/tnpoint.{cpp,hpp}: the npoint/nsegment/tnpoint BLOB types, their
  text <-> VARCHAR casts, and fixed-struct marshalling. Npoint and Nsegment are
  palloc(sizeof) structs (not varlena), so they copy in/out by sizeof like
  Span/STBox rather than by VARSIZE.
- tools/codegen_duck_udfs.py: wire Npoint/Nsegment into the base-value
  marshalling maps and tnpoint into the Spatial<T> type set, so the whole
  inherited Spatial<T> + Temporal<T> surface (205 registrations) is generated.
- Ship the canonical example `ways` network embedded (src/ways_csv.inc) and
  point MEOS at it once at load (ConfigureMeosWaysCsvOnce), mirroring the
  spatial_ref_sys CSV wiring, so route SRID and geometry resolve.
- test/sql/tnpoint.test: type/text I/O, accessors, the network-inherited SRID
  (5676) and position interpolation, and the inherited bbox operators.
Add a (BaseValue*)->by-value scalar shape so the base-value unary accessors
generate from the catalog: a cbuffer/npoint/nsegment value in, a scalar out.
The value is marshalled via BlobTo<Base> (the PTR_IN map) and freed; the UDF
registers over the base accessor type.

On the registered base families this generates radius/SRID/hash for cbuffer
(hash as the native-unsigned UINTEGER, matching the temporal/span/set/box
hashes), route/position/SRID for npoint, and route/startPosition/endPosition/
SRID for nsegment. Base values are not temporal or geo, so no other shape
emits them; the surface is a pure addition with no hand registrations to
retire. Pose accessors follow once the pose type is registered.

Add test/sql/parity/091_baseval_scalar_accessors.test. The npoint position
accessor is called double-quoted because position is a DuckDB reserved word:
the function registers fine but a bare position(x) call fails to parse, the
same reserved-form limitation as the hash-operator names.
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.

2 participants