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):