Skip to content

Spell canonical as the MEOS typedef its cType names, not the platform type#59

Merged
estebanzimanyi merged 1 commit into
MobilityDB:masterfrom
estebanzimanyi:fix/canonical-from-ctype-typedef
Jul 16, 2026
Merged

Spell canonical as the MEOS typedef its cType names, not the platform type#59
estebanzimanyi merged 1 commit into
MobilityDB:masterfrom
estebanzimanyi:fix/canonical-from-ctype-typedef

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

What this changes

On the build-libmeos: true path provision-meos derives the catalog from the self-contained installed headers so struct field types and byte offsets resolve (#45). Parsing those headers, libclang fully resolves the public MEOS/PG typedefs to their platform types while cType keeps the faithful typedef:

slot cType (faithful) canonical (over-resolved)
tint_value_at_timestamptz(…, TimestampTz t, …) TimestampTz long
jsonb_path_exists(const Jsonb *jb, const JsonPath *jp, …) const Jsonb * / const JsonPath * const struct varlena *

A binding generator keys on canonical, so an over-resolved slot loses its semantic type — it marshals a timestamp as a bare long, or drops the function entirely when the platform type is unmarshallable (varlena). The temporal value-accessors and the jsonb path surface then go missing from every generated binding. The source-header parse does not exhibit this because libclang cannot resolve those typedefs there.

This is the canonical-type sibling of #54 (installed headers lose the Doxygen out-param info): the installed-header signatures stay, and the degraded field is re-derived from a faithful source.

The rule

normalize_canonical (parser/typerecover.py, run after reconcile) re-derives each slot's canonical from its faithful cType through the existing _TYPE_MAP — already the single source of truth for how each MEOS/PG typedef is spelled in the IDL. One invariant, applied uniformly to every param, return and struct field:

canonical := _TYPE_MAP[base(cType)] (const / pointer shape preserved) when base(cType) is a known typedef.

  • Idempotent, and a no-op on non-typedef slots (Temporal *, int *) and on the source parse (where canonical already equals the typedef).
  • Complements recover_collapsed_types, which recovers a cType the preprocessor erased to int; this trusts a faithful cType and only re-spells canonical.
  • Leaves cType and offset_bits untouched, so the installed-parse struct byte-offsets stand.

Coverage

tests/test_typerecover.py::test_typedef_canonical_not_platform_resolved asserts tint_value_at_timestamptz.t is TimestampTz and jsonb_path_exists.jb/jp are Jsonb/JsonPath, not their platform resolution.

… type

On the self-contained (installed-header) parse libclang fully resolves the
public MEOS/PG typedefs to their platform types -- TimestampTz to long,
Jsonb * / JsonPath * to varlena * -- while cType keeps the faithful typedef.
A binding generator keys on canonical, so an over-resolved slot loses its
semantic type: it marshals a timestamp as a bare long, or drops the function
entirely when the platform type is unmarshallable (varlena). The temporal
value-accessors (e.g. tint_value_at_timestamptz) and the jsonb path surface
(jsonb_path_exists) then go missing from every generated binding.

Re-derive canonical from the faithful cType through the existing _TYPE_MAP,
so source and installed parses agree on the MEOS type. The pass is idempotent,
a no-op on non-typedef slots (Temporal *, int *), and complements
recover_collapsed_types: that recovers a cType the preprocessor erased to int;
this trusts a faithful cType and only re-spells canonical. Struct byte-offsets
from the installed parse are untouched. Guarded by
test_typedef_canonical_not_platform_resolved.
@estebanzimanyi estebanzimanyi merged commit 922361b into MobilityDB:master Jul 16, 2026
2 checks passed
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