From 50c88b69e8a4732442ce44245ef4e61576214815 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 9 Jul 2026 01:49:49 +0200 Subject: [PATCH] Recover the uint64 PG typedef to uint64_t in the catalog The type-recovery pass rewrites PG-vendored types that libclang collapses to int back to their real spelling from the header text. uint64 was absent from the recovery map, so every uint64 parameter and return (the raquet quadbin cell, all *_hash_extended seeds and results, and other uint64 surfaces) appeared as int in the catalog, truncating 64-bit values to 32 bits in the generated bindings. Add uint64 -> uint64_t, mirroring the existing int64 entry and the H3Index and Quadbin entries that already recover to uint64_t, and add a regression test that asserts the bare-uint64 *_hash_extended surface recovers to uint64_t. --- parser/typerecover.py | 1 + tests/test_typerecover.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/parser/typerecover.py b/parser/typerecover.py index 4acee15..505de8a 100644 --- a/parser/typerecover.py +++ b/parser/typerecover.py @@ -32,6 +32,7 @@ _TYPE_MAP = { "bool": "bool", "int64": "int64_t", + "uint64": "uint64_t", "Timestamp": "Timestamp", "TimestampTz": "TimestampTz", "H3Index": "uint64_t", diff --git a/tests/test_typerecover.py b/tests/test_typerecover.py index 0ee0c7b..45c9c50 100644 --- a/tests/test_typerecover.py +++ b/tests/test_typerecover.py @@ -122,6 +122,17 @@ def test_bool_and_pointer_returns_recovered(self): self.assertEqual(self._ret("bigintset_values"), "int64_t *") self.assertEqual(self._ret("th3index_values"), "uint64_t *") + def test_uint64_recovered(self): + # The bare PG ``uint64`` typedef collapses to ``int`` and must recover + # to ``uint64_t`` (like ``int64`` -> ``int64_t``), else 64-bit values + # (hash seeds, quadbin cells) truncate to 32 bits in generated + # bindings. These ``*_hash_extended`` functions use the bare ``uint64`` + # typedef (not the H3Index/Quadbin aliases), so they recover only when + # the ``uint64`` map entry is present — a guard against dropping it. + self.assertEqual(self._ret("set_hash_extended"), "uint64_t") + self.assertEqual(self._ret("span_hash_extended"), "uint64_t") + self.assertIn("uint64_t", self._param_ctypes("set_hash_extended")) + # ---- genuine-int controls (must NOT be rewritten) ---------------------- def test_genuine_int_left_untouched(self):