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
19 changes: 12 additions & 7 deletions parser/sqlfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -1014,20 +1014,25 @@ def state_deployed_sqlfn(idl: dict) -> tuple[dict, int]:
``sqlName: floatset_in``, the name its ``CREATE FUNCTION`` deploys. When every
signature of a function carries one name, that name is the function's ``sqlfn``
and the signatures drop the ``sqlName`` that only restated it. A function whose
signatures carry several names keeps the tag, each signature its own name; a
``sqlfnBackingOnly`` record, as #classify_backing_sqlfn of parser/portable.py marks
it, keeps its backing tag beside its ``publicSqlName``."""
signatures carry several names keeps the tag when one of them carries it, each
other signature its own name; when none does, as ``floatset_in`` deploys
``floatset_in`` and ``floatsetFromText`` under a ``Set_in`` tagged ``intset_in()``,
its ``sqlfn`` is the name of its first signature, which #attach_sqlfn_map lists
from the tagged wrapper first. A ``sqlfnBackingOnly`` record, as
#classify_backing_sqlfn of parser/portable.py marks it, keeps its backing tag
beside its ``publicSqlName``."""
n = 0
for f in idl.get("functions", []):
sigs = f.get("sqlSignatures")
if not sigs or f.get("sqlfnBackingOnly"):
continue
names = {s.get("sqlName", f["sqlfn"]) for s in sigs}
if len(names) != 1:
names = [s.get("sqlName", f["sqlfn"]) for s in sigs]
if len(set(names)) != 1 and f["sqlfn"] in names:
continue
name = names.pop()
name = names[0]
for s in sigs:
s.pop("sqlName", None)
if s.get("sqlName") == name:
s.pop("sqlName")
if name != f["sqlfn"]:
f["sqlfn"] = name
n += 1
Expand Down
25 changes: 19 additions & 6 deletions tests/test_sqlfn_deployed.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ def test_signatures_carrying_several_names_keep_the_tag(self):
self.assertEqual(fns["ea_dwithin_tgeo_geo"]["sqlSignatures"], sigs)
self.assertEqual(n, 0)

def test_several_names_none_the_tag_take_the_first(self):
# As #test_the_one_name_the_signatures_carry_is_the_sqlfn, once the family's
# wrappers deploy a second name: the tag names a sibling, never this function.
fns, n = _state({"name": "floatset_in", "sqlfn": "intset_in",
"sqlSignatures": [{"args": ["cstring"], "ret": "floatset",
"sqlName": "floatset_in"},
{"args": ["text"], "ret": "floatset",
"sqlName": "floatsetFromText"}]})
self.assertEqual(fns["floatset_in"]["sqlfn"], "floatset_in")
self.assertEqual(fns["floatset_in"]["sqlSignatures"],
[{"args": ["cstring"], "ret": "floatset"},
{"args": ["text"], "ret": "floatset", "sqlName": "floatsetFromText"}])
self.assertEqual(n, 1)

def test_a_backing_tag_stays_beside_its_public_name(self):
fns, n = _state({"name": "adjacent_tbox_tnumber", "sqlfn": "adjacent_bbox",
"sqlfnBackingOnly": True, "publicSqlName": "adjacent",
Expand Down Expand Up @@ -76,19 +90,18 @@ def test_per_type_functions_carry_their_own_name(self):
("contains_cbuffer_cbuffer", "cbuffer_contains")):
self.assertEqual(self.fns[name]["sqlfn"], sqlfn, name)

def test_backing_tags_keep_their_family_name(self):
def test_an_operator_function_carries_its_class_prefixed_name(self):
f = self.fns["adjacent_tbox_tnumber"]
self.assertEqual((f["sqlfn"], f["publicSqlName"]), ("adjacent_bbox", "adjacent"))
self.assertEqual(f["sqlfn"], "tboxAdjacent")

def test_no_function_names_a_family_member_its_signatures_do_not(self):
"""The condition #state_deployed_sqlfn of parser/sqlfn.py reads, asked of the
whole catalog: signatures all carrying one name other than sqlfn, a backing
whole catalog: an sqlfn none of the function's signatures carries, a backing
tag aside."""
other = [f["name"] for f in self.fns.values()
if f.get("sqlSignatures") and not f.get("sqlfnBackingOnly")
and len(names := {s.get("sqlName", f["sqlfn"])
for s in f["sqlSignatures"]}) == 1
and names != {f["sqlfn"]}]
and f["sqlfn"] not in {s.get("sqlName", f["sqlfn"])
for s in f["sqlSignatures"]}]
self.assertEqual(other, [])


Expand Down
Loading