Skip to content

fix(dynamodb): return LastEvaluatedKey when Limit ends the page - #72

Open
kylecannon wants to merge 1 commit into
tyrchen:masterfrom
kylecannon:fix/dynamodb-last-evaluated-key-on-limit
Open

kylecannon wants to merge 1 commit into
tyrchen:masterfrom
kylecannon:fix/dynamodb-last-evaluated-key-on-limit

Conversation

@kylecannon

@kylecannon kylecannon commented Oct 30, 2026 •

Copy link
Copy Markdown

Summary

DynamoDB returns a LastEvaluatedKey whenever Limit stops a Query or Scan, even if nothing is left, and the next page just comes back empty. rustack only returned it when more items followed, so code that pages with Limit stopped a page early compared to AWS. LocalStack behaves the same way as this change. Query, Scan and GSI queries now share one paging helper (take_page in storage.rs) for it.

Returning a key on the last page means the follow-up request always carries a start key, which turned up three places that didn't honour it:

  • queries on tables without a sort key returned the same item forever (provider.rs now maps the missing sort key to the sentinel the storage layer uses)
  • sk = :v queries ignored the start key and looped the same way (collect_with_condition in storage.rs)
  • a scan whose start item had been deleted started over from the top (scan now resumes by position in scan order)

All three now move past the start key.

Test plan

  • Tests in rustack-dynamodb-core for the key on a Limit-sized last page (storage and GSI), paging a hash-only table and an sk = :v query with Limit: 1, and resuming a scan after the start item is deleted.
  • cargo test -p rustack-dynamodb-core passes.

DynamoDB returns a LastEvaluatedKey whenever Limit stops a Query or
Scan, even if nothing is left, and the next page just comes back empty.
rustack only returned it when more items followed, so code that pages
with Limit stopped a page early compared to AWS. LocalStack behaves the
same way as this change. Query, Scan and GSI queries now share one
paging helper for it.

Returning a key on the last page means the follow-up request always
carries a start key, which turned up three places that didn't honour it:
- queries on tables without a sort key returned the same item forever
- `sk = :v` queries ignored the start key and looped the same way
- a scan whose start item had been deleted started over from the top

All three now move past the start key.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant