From fd4d0ceb461f0802777aa538216c3fce006fb8d2 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 13 May 2026 18:41:53 +0200 Subject: [PATCH 1/4] Add shape annotations to meos-meta.json for binding codegens Documents and seeds the per-function shape catalog under functions..shape so binding codegens can resolve array-return lengths, parallel output arrays, multi-input groups, and explicit non-wrappable functions without inventing per-binding metadata. The shape keys are: arrayReturn.lengthFrom (accessor or param), outputArrays (parallel out-parameters sharing the primary length), namedOutputs (scalar out-parameters whose name is neither result nor value), arrayInputGroup (N parallel input slices sharing one count), and skip. Initial coverage closes the 32 GoMEOS codegen TODOs: the *_values family routes through set_num_values / spanset_num_spans / temporal_num_instants accessors; the *_split family declares its time_bins / value_bins / space_bins parallel outputs; the skiplist family is marked skip; tpointseq_make_coords declares its four parallel input arrays; tempsubtype_from_string and geom_min_bounding_radius mark subtype and radius as named outputs. --- meta/meos-meta.json | 97 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/meta/meos-meta.json b/meta/meos-meta.json index 211ccaf..c18ce65 100644 --- a/meta/meos-meta.json +++ b/meta/meos-meta.json @@ -1,4 +1,13 @@ { + "$schema": { + "_doc": "Per-function structural metadata merged into meos-idl.json at parse time. Each entry sits at functions..shape and overrides what bindings can infer from the C signature alone. Field semantics:", + "shape.skip": "Reason string; codegens omit this function entirely.", + "shape.arrayReturn": "The function's return value is an array. lengthFrom describes where the length comes from.", + "shape.arrayReturn.lengthFrom.kind=accessor": "Call func(arg) on one of the function's inputs to get the length. Optional castTo lets the accessor receive a different type (struct-layout-compatible upcast).", + "shape.arrayReturn.lengthFrom.kind=param": "Read the length from the named output parameter of the same function.", + "shape.outputArrays": "List of additional output parameters that are parallel arrays sharing the primary length source.", + "shape.namedOutputs": "List of parameters that are scalar out-parameters but do not use the canonical result/value names." + }, "functions": { "tpointseq_make": { "ownership": "caller", @@ -32,11 +41,95 @@ "interpolation": true, "subtype": "TPoint" } - } + }, + + "bigintset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "dateset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "floatset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "intset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "textset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "tstzset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "geoset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "npointset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + + "spanset_spanarr": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "spanset_num_spans", "arg": "ss" } } } }, + "spanset_sps": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "spanset_num_spans", "arg": "ss" } } } }, + + "tsequence_insts_p": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "temporal_num_instants", "arg": "seq", "castTo": "const Temporal *" } } } }, + "tsequenceset_insts_p": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "tsequenceset_num_instants", "arg": "ss" } } } }, + "tsequenceset_sequences_p": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "temporal_num_sequences", "arg": "ss", "castTo": "const Temporal *" } } } }, + + "temporal_time_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "time_bins" }] + } + }, + "tfloat_value_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "bins" }] + } + }, + "tfloat_value_time_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "value_bins" }, { "param": "time_bins" }] + } + }, + "tint_value_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "bins" }] + } + }, + "tint_value_time_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "value_bins" }, { "param": "time_bins" }] + } + }, + + "tgeo_space_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "space_bins" }] + } + }, + "tgeo_space_time_split": { + "shape": { + "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } }, + "outputArrays": [{ "param": "space_bins" }, { "param": "time_bins" }] + } + }, + + "tpoint_as_mvtgeom": { + "shape": { + "outputArrays": [ + { "param": "gsarr", "lengthFrom": { "kind": "param", "name": "count" } }, + { "param": "timesarr", "lengthFrom": { "kind": "param", "name": "count" } } + ] + } + }, + + "tpointseq_make_coords": { + "shape": { + "arrayInputGroup": { + "params": ["xcoords", "ycoords", "zcoords", "times"], + "count": "count", + "nullable": ["zcoords", "times"] + } + } + }, + + "tempsubtype_from_string": { "shape": { "namedOutputs": ["subtype"] } }, + "geom_min_bounding_radius": { "shape": { "namedOutputs": ["radius"] } }, + + "ttext_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } } } } }, "types": { "TSequence": { "meosType": "TPointSeq" }, "TInstant": { "meosType": "TPointInst" }, "interpType":{ "meosType": "Interpolation" } } -} \ No newline at end of file +} From e58194671e770e48ce00e841f806034b714a50f2 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 14 May 2026 09:08:42 +0200 Subject: [PATCH 2/4] Extend meta/meos-meta.json with nullable + missing output entries Adds shape.nullable across 38 functions covering 52 (function, param) pairs that accept NULL: aggregator transfn state slots, optional shift / scale / duration windows, tile origin overrides, tz_str and extra config strings, geo_as_geojson srs, and tsequenceset_make_gaps maxt. Adds shape.outputArrays for tbox_as_hexwkb / stbox_as_hexwkb (size) and the three *_time_tiles count outputs that the existing auto-detect heuristic does not reach. Lets PyMEOS-CFFI's build_pymeos_functions.py replace its hardcoded nullable_parameters and output_parameters sets with reads from the IDL. --- meta/meos-meta.json | 47 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/meta/meos-meta.json b/meta/meos-meta.json index c18ce65..3b7247d 100644 --- a/meta/meos-meta.json +++ b/meta/meos-meta.json @@ -6,7 +6,9 @@ "shape.arrayReturn.lengthFrom.kind=accessor": "Call func(arg) on one of the function's inputs to get the length. Optional castTo lets the accessor receive a different type (struct-layout-compatible upcast).", "shape.arrayReturn.lengthFrom.kind=param": "Read the length from the named output parameter of the same function.", "shape.outputArrays": "List of additional output parameters that are parallel arrays sharing the primary length source.", - "shape.namedOutputs": "List of parameters that are scalar out-parameters but do not use the canonical result/value names." + "shape.namedOutputs": "List of parameters that are scalar out-parameters but do not use the canonical result/value names.", + "shape.nullable": "List of parameter names that accept NULL. Lets bindings emit optional/None-friendly signatures.", + "shape.arrayInputGroup": "N parallel input arrays sharing one count. Members listed in arrayInputGroup.nullable accept NULL/nil." }, "functions": { "tpointseq_make": { @@ -125,7 +127,48 @@ "tempsubtype_from_string": { "shape": { "namedOutputs": ["subtype"] } }, "geom_min_bounding_radius": { "shape": { "namedOutputs": ["radius"] } }, - "ttext_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } } } } + "ttext_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } } } }, + + "tbox_as_hexwkb": { "shape": { "outputArrays": [{ "param": "size" }] } }, + "stbox_as_hexwkb": { "shape": { "outputArrays": [{ "param": "size" }] } }, + "tintbox_value_time_tiles": { "shape": { "outputArrays": [{ "param": "count" }], "nullable": ["xorigin", "torigin"] } }, + "tfloatbox_value_time_tiles":{ "shape": { "outputArrays": [{ "param": "count" }], "nullable": ["xorigin", "torigin"] } }, + "stbox_space_time_tiles": { "shape": { "outputArrays": [{ "param": "count" }], "nullable": ["duration"] } }, + + "meos_initialize": { "shape": { "nullable": ["tz_str"] } }, + "meos_set_intervalstyle": { "shape": { "nullable": ["extra"] } }, + "temporal_append_tinstant": { "shape": { "nullable": ["maxt"] } }, + "temporal_as_mfjson": { "shape": { "nullable": ["srs"] } }, + "tstzspan_shift_scale": { "shape": { "nullable": ["shift", "duration"] } }, + "tstzset_shift_scale": { "shape": { "nullable": ["shift", "duration"] } }, + "tstzspanset_shift_scale": { "shape": { "nullable": ["shift", "duration"] } }, + "temporal_shift_scale_time": { "shape": { "nullable": ["shift", "duration"] } }, + "tbox_make": { "shape": { "nullable": ["p", "s"] } }, + "stbox_make": { "shape": { "nullable": ["p", "s"] } }, + "stbox_shift_scale_time": { "shape": { "nullable": ["shift", "duration"] } }, + "temporal_tcount_transfn": { "shape": { "nullable": ["state", "interval"] } }, + "temporal_extent_transfn": { "shape": { "nullable": ["p"] } }, + "tnumber_extent_transfn": { "shape": { "nullable": ["box"] } }, + "tspatial_extent_transfn": { "shape": { "nullable": ["box"] } }, + "tbool_tand_transfn": { "shape": { "nullable": ["state"] } }, + "tbool_tor_transfn": { "shape": { "nullable": ["state"] } }, + "tbox_shift_scale_time": { "shape": { "nullable": ["shift", "duration"] } }, + "tint_tmin_transfn": { "shape": { "nullable": ["state"] } }, + "tfloat_tmin_transfn": { "shape": { "nullable": ["state"] } }, + "tint_tmax_transfn": { "shape": { "nullable": ["state"] } }, + "tfloat_tmax_transfn": { "shape": { "nullable": ["state"] } }, + "tint_tsum_transfn": { "shape": { "nullable": ["state"] } }, + "tfloat_tsum_transfn": { "shape": { "nullable": ["state"] } }, + "tnumber_tavg_transfn": { "shape": { "nullable": ["state"] } }, + "ttext_tmin_transfn": { "shape": { "nullable": ["state"] } }, + "ttext_tmax_transfn": { "shape": { "nullable": ["state"] } }, + "timestamptz_tcount_transfn":{ "shape": { "nullable": ["state", "interval"] } }, + "tstzset_tcount_transfn": { "shape": { "nullable": ["state", "interval"] } }, + "tstzspan_tcount_transfn": { "shape": { "nullable": ["state", "interval"] } }, + "tstzspanset_tcount_transfn":{ "shape": { "nullable": ["state", "interval"] } }, + "timestamptz_extent_transfn":{ "shape": { "nullable": ["p"] } }, + "tsequenceset_make_gaps": { "shape": { "nullable": ["maxt"] } }, + "geo_as_geojson": { "shape": { "nullable": ["srs"] } } }, "types": { "TSequence": { "meosType": "TPointSeq" }, From e90c07d155d2a0d5fd0c1b9ff1947f9c9a4571fd Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 14 May 2026 15:35:17 +0200 Subject: [PATCH 3/4] Add stbox_quad_split shape entry stbox_quad_split returns an STBox array whose length lives in its trailing int *count parameter. Without the entry, bindings expose count as a user-facing input. --- meta/meos-meta.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meta/meos-meta.json b/meta/meos-meta.json index 3b7247d..de12b8b 100644 --- a/meta/meos-meta.json +++ b/meta/meos-meta.json @@ -105,6 +105,10 @@ } }, + "stbox_quad_split": { + "shape": { "arrayReturn": { "lengthFrom": { "kind": "param", "name": "count" } } } + }, + "tpoint_as_mvtgeom": { "shape": { "outputArrays": [ From 21b31c10e91aef7a981f2d2465fb18bdd56310ba Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 14 May 2026 16:40:12 +0200 Subject: [PATCH 4/4] Add shape entries for cbufferset_values and poseset_values Match the existing geoset_values pattern. Bindings now know the length comes from set_num_values rather than treating these as free-floating Cbuffer ** / Pose ** returns. --- meta/meos-meta.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta/meos-meta.json b/meta/meos-meta.json index de12b8b..b8961c0 100644 --- a/meta/meos-meta.json +++ b/meta/meos-meta.json @@ -53,6 +53,8 @@ "tstzset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, "geoset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, "npointset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "cbufferset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, + "poseset_values": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "set_num_values", "arg": "s" } } } }, "spanset_spanarr": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "spanset_num_spans", "arg": "ss" } } } }, "spanset_sps": { "shape": { "arrayReturn": { "lengthFrom": { "kind": "accessor", "func": "spanset_num_spans", "arg": "ss" } } } },