From 7db282752024d578a29324955179756e76ba5698 Mon Sep 17 00:00:00 2001 From: kshitij Date: Mon, 3 Aug 2026 17:24:25 +0530 Subject: [PATCH] refactor(state): chunk the batched tip-row IN clause at 900 ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify-pass fold: SQLITE_MAX_VARIABLE_NUMBER is 999 on pre-3.32\nbuilds (which the repo still supports — the trigram-availability\nmachinery exists for exactly that class), and limit=10000\nlist_sessions_rich callers exist in web_server. Chunk inside the\nbatch helper — the single choke point — so no call site can overflow. --- hermes_state_portability.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hermes_state_portability.py b/hermes_state_portability.py index 0bee0b2dbf..fcb0d54ab2 100644 --- a/hermes_state_portability.py +++ b/hermes_state_portability.py @@ -156,6 +156,21 @@ class SessionPortabilityMixin: ids = [sid for sid in session_ids if sid] if not ids: return {} + # Old SQLite builds cap bound variables at 999 + # (SQLITE_MAX_VARIABLE_NUMBER); large pages (limit=10000 callers + # exist) could exceed it. Chunk the IN list so the helper is safe at + # any page size — this is the single choke point for the enriched + # multi-row fetch, so the bound lives here, not at call sites. + _CHUNK = 900 + if len(ids) > _CHUNK: + result: Dict[str, Dict[str, Any]] = {} + for start in range(0, len(ids), _CHUNK): + result.update( + self._get_session_rich_rows_batch( + ids[start:start + _CHUNK], compact_rows=compact_rows + ) + ) + return result # Same read-your-writes guarantee as list_sessions_rich. self.flush_token_counts() _sel = self._compact_session_cols() if compact_rows else "s.*"