refactor composer to use sqlalchemy, avoid string concatenations and follow conventions

This commit is contained in:
2026-06-03 12:10:30 -03:00
parent cbc7df8c60
commit be09fcde2c
16 changed files with 546 additions and 273 deletions

56
api/composer/aliases.py Normal file
View File

@@ -0,0 +1,56 @@
"""Alias allocation for the composer.
Every table referenced in a composed query gets a short, query-unique alias.
`AliasMap` owns that allocation so the rest of the composer never threads a
bare dict around: ask it for a table's alias (allocating on first use) or for a
qualified `exp.Column`, and it remembers the assignment.
Allocation strategy (stable — golden SQL depends on it): first letter, then the
first two/three letters, then the full name, then a numbered `<first><n>` on
collision. So `loan→l`, `account→a`, `district→d`.
"""
from __future__ import annotations
from sqlglot import exp
def _alloc(table: str, used: set[str]) -> str:
"""Pick an alias for `table` not already in `used`."""
for base in (table[:1], table[:2], table[:3], table):
if base and base not in used:
return base
i = 1
while True:
cand = f"{table[:1]}{i}"
if cand not in used:
return cand
i += 1
class AliasMap:
"""Maps table name → alias, allocating on first request."""
def __init__(self) -> None:
self._by_table: dict[str, str] = {}
def has(self, table: str) -> bool:
return table in self._by_table
def alias(self, table: str) -> str:
"""Return `table`'s alias, allocating a fresh unique one if needed."""
if table not in self._by_table:
self._by_table[table] = _alloc(table, set(self._by_table.values()))
return self._by_table[table]
def col(self, table: str, column: str) -> exp.Column:
"""A quoted, alias-qualified column reference for the final tree."""
return exp.column(column, table=self.alias(table), quoted=True)
def aliased_table(self, table: str) -> exp.Expression:
"""`"<table>" AS "<alias>"` for FROM / JOIN."""
return exp.alias_(exp.to_table(table, quoted=True), self.alias(table), quoted=True)
def tables(self) -> list[str]:
"""Sorted names of every table that has been referenced."""
return sorted(self._by_table)