Source code for recon_gen.common.sql.money

"""Dialect-aware cents → dollars projection for read-boundary SQL.

Per AO.1: storage moves to BIGINT integer cents on every dialect.
Wrap a money column (BIGINT cents) in this helper anywhere the renderer
needs dollars. The matview SQL math stays in cents (integer-safe,
no float dust); this helper is the only place the dollar projection
happens.

Paired with ``recon_gen.common.money.Cents.from_db`` on the Python-read
side — same boundary, two consumers (dataset SQL projections + spine
detect helpers).
"""

from __future__ import annotations

from recon_gen.common.sql.dialect import Dialect


[docs] def cents_to_dollars_sql(col: str, *, dialect: Dialect) -> str: """Return a SQL expression that projects ``col`` (BIGINT cents) to dollars. Postgres + Oracle: ``BIGINT / NUMERIC(20,2)`` literal promotes the division to NUMERIC (exact, no float fallback). SQLite: explicit ``CAST(... AS REAL) / 100.0`` to force float division — without the CAST, SQLite's INTEGER / INTEGER would integer-truncate (7500 / 100 = 75 with no decimal, dropping the cents portion entirely). ``col`` is the bare column reference (caller has already qualified it as needed, e.g., ``"t.amount_money"``). Returns the parenthesized expression ready to drop into a SELECT list or WHERE clause. """ return f"({col} / 100.0)"