From 376d921e16e32e0065e176b297b45de22ae043f1 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 11 Jun 2026 19:26:13 +0200 Subject: [PATCH] Recover the jsonb Jsonb and jsonpath JsonPath collapsed C types libclang collapses the PG-vendored Jsonb (struct JsonbPair) and JsonPath (struct JsonPathParseItem) pointer types to int during header parsing, the same mechanism already handled for GSERIALIZED/GBOX/Interval/DateADT. Add both to the type-recovery map so the temporal-JSONB (tjsonb) and jsonbset functions carry their real Jsonb*/JsonPath* signatures in the generated IDL that every binding consumes (verified: jsonbset_value_n result recovers to Jsonb**). --- parser/typerecover.py | 2 ++ tests/test_typerecover.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/parser/typerecover.py b/parser/typerecover.py index 01d8153..49cff42 100644 --- a/parser/typerecover.py +++ b/parser/typerecover.py @@ -44,6 +44,8 @@ "GBOX": "GBOX", "BOX3D": "BOX3D", "AFFINE": "AFFINE", + "Jsonb": "Jsonb", + "JsonPath": "JsonPath", } _NAMES = "|".join(sorted(_TYPE_MAP, key=len, reverse=True)) diff --git a/tests/test_typerecover.py b/tests/test_typerecover.py index ed10993..de68f07 100644 --- a/tests/test_typerecover.py +++ b/tests/test_typerecover.py @@ -81,6 +81,22 @@ def test_no_gserialized_left_collapsed_to_int(self): self.assertGreater(len(geo_fns), 50, "GSERIALIZED* collapsed toward int — typerecover regression?") + # ---- jsonb Jsonb / jsonpath JsonPath (opaque PG types, collapse to int) - + + def test_jsonb_recovered_when_tjsonb_present(self): + # The temporal-JSONB surface is built only when MEOS is compiled with + # JSON=ON, so this assertion is conditional on the parsed source + # carrying it (skipped otherwise to stay source-agnostic). + jsonb_fns = [n for n in self.by_name + if "jsonb" in n.lower() or "tjsonb" in n.lower()] + if not jsonb_fns: + self.skipTest("source parsed without the JSON=ON tjsonb surface") + # An out-parameter that pre-fix came back as ``int **``. + self.assertIn("Jsonb **", self._param_ctypes("jsonbset_value_n")) + carriers = [f for f in self.by_name.values() if "Jsonb *" in json.dumps(f)] + self.assertGreater(len(carriers), 20, + "Jsonb* collapsed toward int — typerecover regression?") + # ---- other PG-vendored opaque types (Interval / DateADT / Datum / ...) - def test_interval_params_recovered(self):