From dace1f7e27df11acd15d31aeaf9d8e70c9956b48 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Sun, 18 Oct 2026 10:26:29 +0200 Subject: [PATCH] Read the alternative names of a wrapper declared inline parser/altsqlfn.py reads the @altsqlfn of a PostgreSQL wrapper from the doxygen block right before its `Datum Name(PG_FUNCTION_ARGS)`, and takes the wrapper declared `inline` or `static` as well, as the #_DATUM pattern of parser/sqlfn.py reads it. MobilityDB declares 753 of its wrappers `inline Datum`, among them Tnumber_wavg_transfn, the transition of wAvg. Witness: over MobilityDB branch sql/wavg-engine-name, which states `@altsqlfn wAvgAgg()` on Tnumber_wavg_transfn, the catalog gives the three wAvg entries altSqlName wAvgAgg, where the pattern that wants `Datum` right after the block gives them none. Measured: over that branch the catalog differs from the one master's parser derives in those three aggregate entries alone, 157 aggregate entries carrying an altSqlName against 154, no function differing; over MobilityDB fa02361fa6 it is byte for byte the catalog master's parser derives. tests/test_altsqlfn.py states an `inline` transition and a `static inline` scalar wrapper, a test that fails on master's parser. The suite runs 561 tests with the same three failures as master (test_family, test_struct_layout twice). Why: an engine reads the name it registers from altSqlName, so a tag the parser does not read leaves the engine on a name it cannot hold. --- parser/altsqlfn.py | 7 ++++--- tests/test_altsqlfn.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/parser/altsqlfn.py b/parser/altsqlfn.py index 6798f25..f1e3e5e 100644 --- a/parser/altsqlfn.py +++ b/parser/altsqlfn.py @@ -52,9 +52,10 @@ from parser.sqlfn import _CSQLFN_END, _meos_to_mdb, _wrapper_sql_sigs from parser.typescope import SQL_ALIASES, TypeFacts -# A doxygen block closing right before the wrapper's `Datum Name(PG_FUNCTION_ARGS)`. -_WRAPPER_BLOCK = re.compile(r"/\*\*((?:(?!\*/).)*)\*/\s*Datum\s+(\w+)\s*\(\s*PG_FUNCTION_ARGS", - re.S) +# A doxygen block closing right before the wrapper's `Datum Name(PG_FUNCTION_ARGS)`, which the +# wrapper may declare `inline` or `static`, as #_DATUM of parser/sqlfn.py reads it. +_WRAPPER_BLOCK = re.compile(r"/\*\*((?:(?!\*/).)*)\*/\s*(?:(?:static|inline)\s+)*Datum\s+(\w+)" + r"\s*\(\s*PG_FUNCTION_ARGS", re.S) _NAME = re.compile(r"(\w+)\s*\(\)") # The MEOS spelling of a type PostgreSQL spells otherwise (`integer` is `int4`). _MEOS_SPELLING = {sql: meos for meos, sql in SQL_ALIASES.items()} diff --git a/tests/test_altsqlfn.py b/tests/test_altsqlfn.py index 43f53fe..b1be275 100644 --- a/tests/test_altsqlfn.py +++ b/tests/test_altsqlfn.py @@ -300,6 +300,36 @@ def test_unpaired_and_conflicting_names_are_errors(self): self.assertIn("Span_union_finalfn", errors[0]) self.assertIn("Tfloat_tmin_transfn", errors[1]) + def test_a_wrapper_declared_inline_states_its_names(self): + # The wrappers of #WRAPPERS, declared `inline` and `static inline` as MobilityDB + # declares many of its wrappers + text = """ +/** + * @sqlfn wAvgTransition() + * @sqlaggfn wAvg() + * @altsqlfn wAvgAgg() + */ +inline Datum +Tnumber_wavg_transfn(PG_FUNCTION_ARGS) +{ +} + +/** + * @sqlfn abs() + * @altsqlfn intAbs(), floatAbs() + */ +static inline Datum +Tnumber_abs(PG_FUNCTION_ARGS) +{ +} +""" + with tempfile.TemporaryDirectory() as tmp: + (Path(tmp) / "w.c").write_text(text) + names, errors = aggregate_alt_names(tmp) + wrappers = wrapper_names(tmp) + self.assertEqual((names, errors), ({"wAvg": "wAvgAgg"}, [])) + self.assertEqual(wrappers, {"Tnumber_abs": (["abs"], ["intAbs", "floatAbs"])}) + class AltSqlNameContractTests(unittest.TestCase): """Over the generated catalog."""