Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion parser/sqlfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@
# operators lost their SQL name that way).
_FNDEF = re.compile(r"\*/\s*\n(?:[^\n(){};=]+\n)?(?:[\w\s*]+?\s)?(\w+)\s*\(")
_SQLFN = re.compile(r"@sqlfn\s+(\w+)\s*\(\)")
_SQLOP = re.compile(r"@sqlop\s+@p\s+(\S+)")
# The operator stops at a comma, mirroring `_SQLFN`'s `(\w+)\s*\(\)`: a block naming several
# SQL functions lists their operators the same comma-separated way
# (`@sqlop @p ->, @p ->>` beside `@sqlfn a(), b()`), and a PostgreSQL operator name never
# contains a comma. `(\S+)` ran past it and published the comma as part of the operator.
_SQLOP = re.compile(r"@sqlop\s+@p\s+([^\s,]+)")
_DATUM = re.compile(r"Datum\s+(\w+)\s*\(\s*PG_FUNCTION_ARGS")
# `CREATE [OR REPLACE] FUNCTION name(` — the SQL-facing signature; the wrapper it
# binds is in the trailing `AS 'MODULE_PATHNAME', '<Wrapper>'`.
Expand Down
24 changes: 24 additions & 0 deletions tests/test_sqlfn_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ def _trees(self, d):
(mdb / "y.c").write_text(MDB_C)
return str(meos), str(mdb)

def test_multi_op_tag_keeps_the_operator_without_its_comma(self):
"""A block naming several SQL functions lists their operators the same
comma-separated way `@sqlfn` lists the names, so the operator ends at the
comma. Reading to the next whitespace published `->,` as the operator."""
src = """
/**
* @ingroup meos_json_json
* @brief Extract a field from a temporal JSONB value
* @sqlfn tjsonbObjectField(), tjsonbObjectFieldText()
* @sqlop @p ->, @p ->>
*/
Temporal *
tjsonb_object_field(const Temporal *temp, const text *key)
{
}
"""
with tempfile.TemporaryDirectory() as d:
meos = Path(d) / "meos"
meos.mkdir()
(meos / "j.c").write_text(src)
direct = _meos_direct_sql(str(meos))
self.assertEqual(direct.get("tjsonb_object_field"),
("tjsonbObjectField", "->"))

def test_direct_map_needs_sqlfn_and_skips_csqlfn_blocks(self):
with tempfile.TemporaryDirectory() as d:
meos, _ = self._trees(d)
Expand Down
Loading