Found during ACE-083 review (#199), measured identical on main @ 439ecd1. Not a regression, but it is the same false-clean class ACE-083 spent two review rounds closing, sitting two functions away from the case-folding fix that branch does land.
SELECT SUM(ORDERS.total_amount) FROM ORDERS JOIN ORDER_ITEMS ON ORDER_ITEMS.order_id = ORDERS.id
check_table_scope returns no refusal, because it lowercases before matching. assemble_receipt then emits:
{"aggregate": "SUM(ORDERS.total_amount)", "status": "not_multiplied", "joins": [], "findings": []}
That is a positive claim that the rows were not duplicated. They were.
Cause. runtime.py::_one_side_facing_many and ::_many_side_facing_one compare table names without folding, while check_table_scope folds and _tkey exists precisely for this. Unquoted identifiers fold case, and the module states that convention in check_column_scope's own comment.
Why it matters beyond the contrived spelling. Snowflake and Oracle catalogs hand identifiers back uppercase, so a model introspected there carries uppercase table names while generated SQL is commonly lowercase, or the reverse. ACE-083 fixed exactly this hazard for the grain-vs-join-key comparison (_cte_edge now folds both sides); these two helpers were out of its scope.
Fix is likely one line each: fold both sides through _tkey, as _cte_edge now does. Needs a regression test with an uppercase-spelled statement over the existing fan fixture.
Found during ACE-083 review (#199), measured identical on
main@439ecd1. Not a regression, but it is the same false-clean class ACE-083 spent two review rounds closing, sitting two functions away from the case-folding fix that branch does land.check_table_scopereturns no refusal, because it lowercases before matching.assemble_receiptthen emits:{"aggregate": "SUM(ORDERS.total_amount)", "status": "not_multiplied", "joins": [], "findings": []}That is a positive claim that the rows were not duplicated. They were.
Cause.
runtime.py::_one_side_facing_manyand::_many_side_facing_onecompare table names without folding, whilecheck_table_scopefolds and_tkeyexists precisely for this. Unquoted identifiers fold case, and the module states that convention incheck_column_scope's own comment.Why it matters beyond the contrived spelling. Snowflake and Oracle catalogs hand identifiers back uppercase, so a model introspected there carries uppercase table names while generated SQL is commonly lowercase, or the reverse. ACE-083 fixed exactly this hazard for the grain-vs-join-key comparison (
_cte_edgenow folds both sides); these two helpers were out of its scope.Fix is likely one line each: fold both sides through
_tkey, as_cte_edgenow does. Needs a regression test with an uppercase-spelled statement over the existing fan fixture.