Files
langgraph/libs/checkpoint-sqlite/tests
Elior Nataf Lackritzandlylelllll ecc420e7fe fix(checkpoint-sqlite): walk delta ancestors by parent pointer
Stage 1 of the sqlite delta history filtered `checkpoint_id <= target` and
streamed `ORDER BY checkpoint_id DESC`. Both predicates encode the same extra
assumption: that every child's checkpoint id sorts above its parent's.

Ancestry is defined by `parent_checkpoint_id`, and nothing in the contract
requires ids to be monotonic. A parent whose id sorted above its child's was
dropped from the stream, so its stored value and its writes were lost with no
error raised. Removing the range filter alone would not help: in DESC order
that parent arrives before the target, so the walk passes it before it has
started. A single-pass ordered stream cannot express this walk.

Replace it with a recursive CTE anchored at the target that follows
`parent_checkpoint_id`. Rows arrive in walk order, so `step_walk_with_row`
keeps its existing shape, and the query now reads only true ancestors instead
of every row at or below the target, which is strictly less IO than before.

Following pointers can loop where a bounded id scan could not, and a loop is
reachable through `put` alone rather than only by corruption: it writes with
`INSERT OR REPLACE`, so re-putting an existing checkpoint id under a
descendant's config repoints that checkpoint at its own descendant. The walk
therefore stops on a repeated checkpoint id. sqlite yields recursive rows
lazily, so abandoning the cursor ends the recursion instead of waiting on it.

Postgres needs no equivalent change. It pages the whole thread and follows
parent pointers already, so it returns the correct history for this scenario.

Fixes #8550

Co-authored-by: lylelllll <59271327+lylelllll@users.noreply.github.com>
2026-08-06 10:56:58 -04:00
..