fix: offset-without-limit was silently ignored in get_messages

Review finding: get_messages(offset=N) with no limit dropped the OFFSET
entirely. SQLite requires a LIMIT clause for OFFSET, so emit LIMIT -1
(unbounded) when only offset is given. Regression test added.
This commit is contained in:
kshitijk4poor 2026-07-08 17:30:17 +05:30 committed by kshitij
parent 4f220fc88b
commit 7570bb4ad4
2 changed files with 12 additions and 2 deletions

View file

@ -3764,6 +3764,8 @@ class SessionDB:
When ``limit`` is provided, returns at most ``limit`` messages
starting from ``offset`` (0-based, in insertion order). Enables
pagination for the API endpoint to avoid loading entire transcripts.
``offset`` alone (without ``limit``) also pages SQLite requires a
LIMIT clause for OFFSET, so it's emitted as ``LIMIT -1`` (unbounded).
"""
active_clause = "" if include_inactive else " AND active = 1"
sql = (
@ -3771,9 +3773,10 @@ class SessionDB:
f"{active_clause} ORDER BY id"
)
params: list = [session_id]
if limit is not None:
if limit is not None or offset:
# SQLite's OFFSET requires LIMIT; -1 means "no limit".
sql += " LIMIT ? OFFSET ?"
params.extend([limit, offset])
params.extend([-1 if limit is None else limit, offset])
with self._lock:
cursor = self._conn.execute(sql, params)
rows = cursor.fetchall()

View file

@ -5506,3 +5506,10 @@ class TestGetMessagesPagination:
db._conn.commit()
page = db.get_messages("s1", limit=3, offset=0)
assert [m["content"] for m in page] == ["msg-2", "msg-3", "msg-4"]
def test_offset_without_limit_pages(self, db):
"""offset alone must not be silently ignored (review finding):
SQLite needs LIMIT for OFFSET, emitted as LIMIT -1."""
self._seed(db, n=5)
rows = db.get_messages("s1", offset=3)
assert [m["content"] for m in rows] == ["msg-3", "msg-4"]