fix(tradein-estimator): restore CAST in IS NOT NULL predicates (revert audit #9)
PR #509 removed CAST(:target_year AS integer) and CAST(:target_house_type AS text) from the IS NOT NULL predicates in _fetch_analogs, citing audit finding #9 (perf). This broke production: psycopg3 prepared statement could not determine $4 type when target_house_type=None, raising AmbiguousParameter at plan time. The CAST in the THEN branch is not enough — PG planner needs the type to evaluate IS NOT NULL itself. The inline comment at lines 814-816 explicitly documented this requirement; PR #509 misread the audit finding. Per-row CAST cost on ≤300 rows is negligible vs production breakage. Restoring CAST forms; THEN-branch CASTs untouched (they were never removed). Verified prod stack trace 2026-05-24 ~12:25 (target_year=1978, target_house_type=None).
This commit is contained in:
parent
ac57b8e905
commit
4a2a804296
1 changed files with 4 additions and 4 deletions
|
|
@ -881,13 +881,13 @@ def _fetch_analogs(
|
||||||
-- без типа → PostgreSQL "could not determine data type of parameter"
|
-- без типа → PostgreSQL "could not determine data type of parameter"
|
||||||
-- (AmbiguousParameter). Явный тип снимает неоднозначность.
|
-- (AmbiguousParameter). Явный тип снимает неоднозначность.
|
||||||
+ CASE
|
+ CASE
|
||||||
WHEN :target_year IS NOT NULL
|
WHEN CAST(:target_year AS integer) IS NOT NULL
|
||||||
AND year_built IS NOT NULL
|
AND year_built IS NOT NULL
|
||||||
THEN abs(year_built - CAST(:target_year AS integer)) / 12.0
|
THEN abs(year_built - CAST(:target_year AS integer)) / 12.0
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END
|
END
|
||||||
+ CASE
|
+ CASE
|
||||||
WHEN :target_house_type IS NOT NULL
|
WHEN CAST(:target_house_type AS text) IS NOT NULL
|
||||||
AND house_type IS NOT NULL
|
AND house_type IS NOT NULL
|
||||||
AND house_type <> CAST(:target_house_type AS text)
|
AND house_type <> CAST(:target_house_type AS text)
|
||||||
THEN 1.5
|
THEN 1.5
|
||||||
|
|
@ -900,13 +900,13 @@ def _fetch_analogs(
|
||||||
ST_Distance(geom::geography, ST_MakePoint(:lon, :lat)::geography)
|
ST_Distance(geom::geography, ST_MakePoint(:lon, :lat)::geography)
|
||||||
/ 1000.0
|
/ 1000.0
|
||||||
+ CASE
|
+ CASE
|
||||||
WHEN :target_year IS NOT NULL
|
WHEN CAST(:target_year AS integer) IS NOT NULL
|
||||||
AND year_built IS NOT NULL
|
AND year_built IS NOT NULL
|
||||||
THEN abs(year_built - CAST(:target_year AS integer)) / 12.0
|
THEN abs(year_built - CAST(:target_year AS integer)) / 12.0
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END
|
END
|
||||||
+ CASE
|
+ CASE
|
||||||
WHEN :target_house_type IS NOT NULL
|
WHEN CAST(:target_house_type AS text) IS NOT NULL
|
||||||
AND house_type IS NOT NULL
|
AND house_type IS NOT NULL
|
||||||
AND house_type <> CAST(:target_house_type AS text)
|
AND house_type <> CAST(:target_house_type AS text)
|
||||||
THEN 1.5
|
THEN 1.5
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue