# UNDF: UNDF-2026-000000542 # sqlalchemy-0003: evaluated_keys list → set in _apply_evaluators() ## Severity MEDIUM ## Location `lib/sqlalchemy/orm/bulk_persistence.py` — `_apply_evaluators()` (approx. line 1873) ## Description `evaluated_keys = list(value_evaluators.keys())` converts a dict's key view to a plain list. The list is then used for: 1. `c.key not in evaluated_keys` — O(K) membership scan inside a set comprehension over `prefetch_cols` (one test per column) 2. `.difference(evaluated_keys)` — called on a set; this is O(P×K) rather than the O(P) it would be with a set argument Fix: `evaluated_keys = set(value_evaluators)` (or just use `value_evaluators` directly for membership, since dict `in` is O(1)). ## Defective code (lines 1873–1889) ```python evaluated_keys = list(value_evaluators.keys()) # ← plain list to_prefetch = { c for c in prefetch_cols if c.key in effective_params and c in mapper._columntoproperty and c.key not in evaluated_keys # ← O(K) linear scan per column } to_expire = { mapper._columntoproperty[c].key for c in postfetch_cols if c in mapper._columntoproperty }.difference(evaluated_keys) # ← set.difference(list) is O(P×K) ``` ## Fix ```diff --- a/lib/sqlalchemy/orm/bulk_persistence.py +++ b/lib/sqlalchemy/orm/bulk_persistence.py @@ -1873,1 +1873,1 @@ - evaluated_keys = list(value_evaluators.keys()) + evaluated_keys = set(value_evaluators) ``` ## Complexity - Before: O(C×K) for the `to_prefetch` comprehension, O(P×K) for `.difference()` - After: O(C) + O(P) — both operations drop to O(1) membership