Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
575 changes: 278 additions & 297 deletions src/generated/generated_temporal_udfs_0.cpp

Large diffs are not rendered by default.

947 changes: 463 additions & 484 deletions src/generated/generated_temporal_udfs_1.cpp

Large diffs are not rendered by default.

671 changes: 306 additions & 365 deletions src/generated/generated_temporal_udfs_2.cpp

Large diffs are not rendered by default.

739 changes: 408 additions & 331 deletions src/generated/generated_temporal_udfs_3.cpp

Large diffs are not rendered by default.

929 changes: 483 additions & 446 deletions src/generated/generated_temporal_udfs_4.cpp

Large diffs are not rendered by default.

968 changes: 470 additions & 498 deletions src/generated/generated_temporal_udfs_5.cpp

Large diffs are not rendered by default.

770 changes: 360 additions & 410 deletions src/generated/generated_temporal_udfs_6.cpp

Large diffs are not rendered by default.

1,004 changes: 520 additions & 484 deletions src/generated/generated_temporal_udfs_7.cpp

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions test/sql/cell_index_spatial_surface.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# name: test/sql/cell_index_spatial_surface.test
# description: The tspatial_* inherited surface covers the types the catalog declares it for.
# A cell index is spatial, but MobilityDB publishes none of asText/asEWKT/SRID/
# setSRID/transform over a cell temporal, so neither does the binding.
# group: [sql]

require mobilityduck

# ── a cell temporal renders through its own text form ───────────────────────
# This is the path MobilityDB uses (CREATE FUNCTION asText(ts2cell) -> Temporal_as_text),
# and it is what carries the cell's own spelling.
query I
SELECT '{47c3c3@2000-01-01}'::ts2cell::VARCHAR;
----
{47c3c3@2000-01-01 00:00:00+01}

# ── the tspatial_* kernels are NOT published over a cell temporal ────────────
# MobilityDB CREATE FUNCTIONs none of these for ts2cell, tquadbin or th3index: swept across
# all 14 mobilitydb/sql/s2cell slices, asEWKT/SRID/setSRID/transform each appear 0 times.
# Binding them anyway reached a MEOS kernel whose own sqlSignatures exclude the cell families,
# which answered "Unknown output function in WKT format for type: s2cell" — a call MobilityDB
# never makes. Absent is the honest answer; these assert it stays absent.

statement error
SELECT asText('{47c3c3@2000-01-01}'::ts2cell);
----
No function matches the given name and argument types 'asText(ts2cell)'

statement error
SELECT asEWKT('{47c3c3@2000-01-01}'::ts2cell);
----
No function matches the given name and argument types 'asEWKT(ts2cell)'

statement error
SELECT SRID('{47c3c3@2000-01-01}'::ts2cell);
----
No function matches the given name and argument types 'SRID(ts2cell)'

statement error
SELECT setSRID('{47c3c3@2000-01-01}'::ts2cell, 4326);
----
No function matches the given name and argument types 'setSRID(ts2cell, INTEGER_LITERAL)'

statement error
SELECT transform('{47c3c3@2000-01-01}'::ts2cell, 3857);
----
No function matches the given name and argument types 'transform(ts2cell, INTEGER_LITERAL)'

# ── the sibling cell families answer identically ────────────────────────────
statement error
SELECT asText(tquadbin(quadbinTileToCell(1,0,1), TIMESTAMPTZ '2024-01-01'));
----
No function matches the given name and argument types 'asText(tquadbin)'

statement error
SELECT transform(tquadbin(quadbinTileToCell(1,0,1), TIMESTAMPTZ '2024-01-01'), 3857);
----
No function matches the given name and argument types 'transform(tquadbin, INTEGER_LITERAL)'

# ── a family owning its temporal surface keeps its OWN text kernel ───────────
# trgeometry appends its reference geometry to the varlena, so it publishes a trgeometry_as_text
# counterpart; asText resolves there and the polygon survives the round trip.
query I
SELECT asText(trgeometry 'Polygon((1 1,2 2,3 1,1 1));Pose(Point(1 1), 0.5)@2000-01-01');
----
POLYGON((1 1,2 2,3 1,1 1));Pose(POINT(1 1),0.5)@2000-01-01 00:00:00+01

# ── SRID reaches the pointcloud temporals the catalog declares it for ────────
query I
SELECT typeof(SRID(tpcpoint('0101000000000000000000F03F0000000000000040', TIMESTAMPTZ '2000-01-01')));
----
INTEGER
38 changes: 33 additions & 5 deletions tools/codegen_duck_udfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,14 @@ def byval_ret_duck(e):
"NpointTypes::tnpoint()",
"PoseTypes::tpose()", "TrgeometryTypes::trgeometry()",
"PosechainTypes::tposechain()"]

# The catalog entry for a function name, so a NAME-keyed scope rule can still consult the
# catalog's own `sqlSignatures` -- populated in main() from the same catalog the surface is
# generated against. reg_scope() takes a name (it is called from a dozen shape functions that
# hold only the name), and threading the whole function dict through all of them would churn
# every call site to reach one branch, so the lookup lives here instead.
FN_BY_NAME = {}

def reg_scope(name):
"""('all', None) generic | ('types', [accessors]) specific | None = not core family.
Resolves the temporal type from the MobilityDB naming convention: a PREFIX
Expand Down Expand Up @@ -497,11 +505,28 @@ def reg_scope(name):
# speed/... live under this MEOS name); geometry-coupled variants auto-exclude.
if name.startswith("tpoint_"):
return ("types", [GEO_TYPES["tgeompoint"], GEO_TYPES["tgeogpoint"]])
# the abstract spatial supertype tspatial_* covers ALL spatial temporal types (the 4 geo
# types + tcbuffer + future spatial families) with type-preserving results (setSRID/
# transform/transformPipeline preserve the operand type; asText/asEWKT return text);
# geometry-coupled variants auto-exclude. This is the TSpatial<T> inherited surface.
if name.startswith("tspatial_") or re.search(r'_tspatial(?=_|$)', name):
# the abstract spatial supertype tspatial_* covers the spatial temporal types with
# type-preserving results (setSRID/transform/transformPipeline preserve the operand type;
# asText/asEWKT return text); geometry-coupled variants auto-exclude. This is the
# TSpatial<T> inherited surface.
# ⛔ WHICH types it covers is the CATALOG's to say, not this list's. Being spatial makes a
# family ELIGIBLE for the surface; it does not mean MobilityDB publishes every tspatial_*
# kernel over it. The cell indexes are the proof: MobilityDB CREATE FUNCTIONs asText for
# them over the GENERIC `Temporal_as_text` and declares asEWKT/SRID/setSRID/transform for
# them nowhere, so a blanket registration binds them to a kernel whose own sqlSignatures
# exclude them -- and tspatial_as_text/as_ewkt/transform then raise "Unknown output
# function in WKT format for type: <cell>" from inside MEOS, on a call MobilityDB never
# makes. Defer to the declared signature set, keeping the blanket only when the catalog
# states nothing (sig_declared_accs answers None), which is its documented fallback.
# ⛔ The catalog restriction applies to the `tspatial_` PREFIX only -- the NAMED inherited
# functions. The `_tspatial_tspatial` SUFFIX names are the positional/topological
# OPERATORS (front/back/left/right/over*), carried by @sqlop rather than @sqlfn, and their
# sqlSignatures are sparse: reading a sparse list as authoritative deletes 132 working
# operator registrations. An operator keeps the blanket.
if name.startswith("tspatial_"):
declared = sig_declared_accs(FN_BY_NAME.get(name) or {})
return ("types", declared or SPATIAL_ALLTYPES)
if re.search(r'_tspatial(?=_|$)', name):
return ("types", SPATIAL_ALLTYPES)
# the geo supertype tgeo covers ONLY geometry+geography (NOT cbuffer/other spatial types).
# Both spellings, as for every other family here: a `tgeo_*` PREFIX (tgeo_stboxes,
Expand Down Expand Up @@ -4511,6 +4536,9 @@ def main():
% (_b, _cb, _seen.most_common(3) or "no pointer-carried function"))
# struct layouts (e.g. Match {i,j}) for the array-return LIST(STRUCT) shape — from the catalog.
STRUCTS.update({s["name"]: s for s in d.get("structs", [])})
# name -> catalog entry, so the name-keyed scope rules can read the function's own
# sqlSignatures (the tspatial_* surface asks which types MobilityDB declares it for).
FN_BY_NAME.update({f["name"]: f for f in fns})
# portable bare-name renderings: operator (@sqlop) -> bareName, straight from the
# catalog's portableAliases (itself generated from the MEOS doxygen @sqlop tags +
# the comparison dialect). The SoT; nothing invented here.
Expand Down
Loading