diff --git a/parser/sqlfn.py b/parser/sqlfn.py index 133e591..61c5c40 100644 --- a/parser/sqlfn.py +++ b/parser/sqlfn.py @@ -494,36 +494,44 @@ def attach_sqlfn_map(idl, meos_src, mdb_src, sql_src=None): def attach_aggfn_map(idl, meos_src): - """Attach `sqlAgg` — the SQL aggregate-role name(s) each aggregate function + """Attach `sqlAggRole` — the aggregate-ROLE name(s) each aggregate function implements, read faithfully from @csqlaggfn in meos/src. This gives an aggregate member its own catalog identity (setUnionTransition, spanUnionFinal) distinct from the identically named binary set/span union FUNCTION, and lets a binding reconstruct the standard PostgreSQL aggregate model (a with its Transition / Combine / Final members) instead of guessing from name suffixes. A member shared by two aggregates (spanset_union_finalfn) carries a - list. Faithful reader: the name is recorded verbatim, no derivation.""" + list. Faithful reader: the name is recorded verbatim, no derivation. + + The ROLE is what this field holds — `setUnionTransition` is the transition + member OF the `setUnion` aggregate. The aggregate itself is `sqlAgg`, named + the way the SQL surface names one where a scalar shares its spelling + (merge / mergeAgg, tMin / tMinAgg).""" a2n = _meos_agg_names(meos_src) n = 0 for f in idl["functions"]: names = a2n.get(f["name"]) if names: - f["sqlAgg"] = names + f["sqlAggRole"] = names n += 1 return idl, n def attach_sqlaggfn_map(idl, meos_src, mdb_src): - """Attach `sqlAggregate` — the SQL AGGREGATE(s) a function's PG wrapper - serves, read from @sqlaggfn in mobilitydb/src over the same @csqlfn chain - that resolves `sqlfn`. + """Attach `sqlAgg` — the SQL AGGREGATE(s) a function's PG wrapper serves, + read from @sqlaggfn in mobilitydb/src over the same @csqlfn chain that + resolves `sqlfn`. - This is the aggregate name a binding registers (`tCount`), and it is a - different fact from both neighbours it sits beside: + `Agg` is how the SQL surface itself names an aggregate where a scalar shares + its spelling (merge / mergeAgg, tMin / tMinAgg), so it is the word for the + field that holds one. This is the name a binding registers (`tCount`), and + it is a different fact from both neighbours it sits beside: - `sqlfn` the CREATE FUNCTION the wrapper backs (`tcount_transfn`) — the - aggregate's transition member, which no user calls; - `sqlAgg` the aggregate-ROLE name from MEOS's @csqlaggfn - (`setUnionTransition`), naming the member within its aggregate. + `sqlfn` the CREATE FUNCTION the wrapper backs (`tcount_transfn`) — + the aggregate's transition member, which no user calls; + `sqlAggRole` the aggregate-ROLE name from MEOS's @csqlaggfn + (`setUnionTransition`), naming the member WITHIN its + aggregate rather than the aggregate. Keeping them apart is what lets a binding tell an aggregate from a function without reading the C symbol's suffix, and it is why `sqlfn` can state the @@ -539,7 +547,7 @@ def attach_sqlaggfn_map(idl, meos_src, mdb_src): if a not in names: names.append(a) if names: - f["sqlAggregate"] = names + f["sqlAgg"] = names n += 1 return idl, n diff --git a/run.py b/run.py index 42fa392..c8fe8f2 100644 --- a/run.py +++ b/run.py @@ -188,7 +188,7 @@ def main(): # implements, so an aggregate member is distinguishable from the identically # named binary set/span union function. One-hop, faithful to the source tag. idl, nagg = attach_aggfn_map(idl, MEOS_SRC) - print(f" Attached {nagg} @csqlaggfn aggregate names", file=sys.stderr) + print(f" Attached {nagg} @csqlaggfn aggregate-role names", file=sys.stderr) # The SQL aggregate a member serves, from @sqlaggfn on its PG wrapper. It # rides the same @csqlfn chain as `sqlfn`, and holds the name a binding # registers the aggregate under, so `sqlfn` is free to state the CREATE diff --git a/tests/test_sqlaggfn.py b/tests/test_sqlaggfn.py index 444ef9e..040e48e 100644 --- a/tests/test_sqlaggfn.py +++ b/tests/test_sqlaggfn.py @@ -86,8 +86,8 @@ def test_aggregate_name_rides_the_csqlfn_chain(self): idl, n = attach_sqlaggfn_map(idl, meos, mdb) by = {f["name"]: f for f in idl["functions"]} self.assertEqual(n, 1) - self.assertEqual(by["temporal_tcount_transfn"]["sqlAggregate"], ["tCount"]) - self.assertNotIn("sqlAggregate", by["temporal_num_instants"]) + self.assertEqual(by["temporal_tcount_transfn"]["sqlAgg"], ["tCount"]) + self.assertNotIn("sqlAgg", by["temporal_num_instants"]) def test_sqlfn_states_the_function_the_wrapper_backs(self): """The two tags coexist on one block: the aggregate name does not take @@ -99,7 +99,7 @@ def test_sqlfn_states_the_function_the_wrapper_backs(self): idl, _ = attach_sqlaggfn_map(idl, meos, mdb) f = idl["functions"][0] self.assertEqual(f["sqlfn"], "tcount_transfn") - self.assertEqual(f["sqlAggregate"], ["tCount"]) + self.assertEqual(f["sqlAgg"], ["tCount"]) if __name__ == "__main__":