"""Storage-encoding library — how a column's raw storage maps to a value the composer can compare against. Some warehouses store logical types in surprising physical encodings (BIRD ships YYMMDD-encoded *integer* "dates", for instance). The composer needs a way to coerce such a column to a comparable value without baking any one dataset's quirk into the generic SQL builder. The model is **defaults with override**: - `DEFAULT_ENCODINGS` ships the generic, reusable patterns here — keyed by the `Column.semantic_type` a dataset declares in `schema_docs.yaml`. - A dataset may add a novel encoding or override a default via the optional `encodings:` section of its `schema_docs.yaml` (carried onto `Recon.encodings`). The dataset always wins. Each encoding is plain data: a map of role → SQL template with a `{col}` placeholder for the (already-qualified) column reference. Today the only role is `as_date` — the expression that yields a DATE for `date_range` filters; new roles are additive. """ from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from api.recon.types import Recon DEFAULT_ENCODINGS: dict[str, dict[str, str]] = { # BIRD-style YYMMDD stored as a 6-digit integer → real DATE. "date_yymmdd": {"as_date": "TO_DATE(LPAD({col}::text, 6, '0'), 'YYMMDD')"}, # Add further reusable patterns here (e.g. epoch_seconds, julian_day) as # they recur across datasets — never a single dataset's one-off quirk. } def effective_encodings(recon: "Recon") -> dict[str, dict[str, str]]: """The encoding map the composer should use for `recon`: built-in defaults overlaid with the dataset's own `encodings` (dataset entries win).""" return {**DEFAULT_ENCODINGS, **(recon.encodings or {})}