make batch operations work

This commit is contained in:
2026-02-16 00:18:20 -05:00
parent c6a78ca054
commit ffd3eda63c
6 changed files with 877 additions and 92 deletions

54
TODO.md
View File

@@ -1,22 +1,7 @@
# JormunDB (Odin rewrite) — TODO
This tracks the rewrite from Zig (ZynamoDB) → Odin (JormunDB), and what's left to stabilize + extend.
This tracks what's left to stabilize + extend the project
## Status Snapshot
### ✅ Ported / Working (core)
- [x] Project layout + Makefile targets (build/run/test/fmt)
- [x] RocksDB bindings / integration
- [x] Core DynamoDB types (AttributeValue / Item / Key / TableDescription, etc.)
- [x] Binary key codec (varint length-prefixed segments)
- [x] Binary item codec (TLV encoding / decoding)
- [x] Storage engine: tables + CRUD + scan/query plumbing
- [x] Table-level RW locks (read ops shared / write ops exclusive)
- [x] HTTP server + request routing via `X-Amz-Target`
- [x] DynamoDB JSON (parse + serialize)
- [x] Expression parsing for Query key conditions (basic support)
---
## Now (MVP correctness + polish)
Goal: "aws cli works reliably for CreateTable/ListTables/PutItem/GetItem/DeleteItem/Scan/Query" with correct DynamoDB-ish responses.
@@ -68,7 +53,8 @@ Goal: "aws cli works reliably for CreateTable/ListTables/PutItem/GetItem/DeleteI
### 5) UpdateItem / conditional logic groundwork
- [x] `UpdateItem` handler registered in router (currently returns clear "not yet supported" error)
- [x] Implement `UpdateItem` (initially minimal: SET for scalar attrs)
- [ ] Add `ConditionExpression` support for Put/Delete/Update (start with simple comparisons)
- [ ] `UpdateItem` needs UPDATED_NEW/UPDATED_OLD response filtering for perfect parity with Dynamo
- [x] Add `ConditionExpression` support for Put/Delete/Update (start with simple comparisons)
- [x] Define internal "update plan" representation (parsed ops → applied mutations)
### 6) Response completeness / options
@@ -86,36 +72,6 @@ Goal: "aws cli works reliably for CreateTable/ListTables/PutItem/GetItem/DeleteI
---
## Bug Fixes Applied This Session
### Pagination (scan + query)
**Bug**: `last_evaluated_key` was set to the key of the *next unread* item (the item at `count == limit`). When the client resumed with that key as `ExclusiveStartKey`, it would seek-then-skip, **dropping one item** from the result set.
**Fix**: Now tracks the key of the *last successfully returned* item. Only emits `LastEvaluatedKey` when we confirm there are more items beyond the returned set (via `has_more` flag).
### Sort key condition filtering
**Bug**: `query()` performed a partition-prefix scan but never applied the sort key condition (=, <, BETWEEN, begins_with, etc.) from `KeyConditionExpression`. All items in the partition were returned regardless of sort key predicates.
**Fix**: `query()` now accepts an optional `Sort_Key_Condition` parameter. The handler extracts it from the parsed `Key_Condition` and passes it through. `evaluate_sort_key_condition()` compares the item's SK attribute against the condition using string comparison (matching DynamoDB's lexicographic semantics for S/N/B keys).
### Write locking
**Bug**: `put_item` and `delete_item` acquired *shared* (read) locks. Multiple concurrent writes to the same table could interleave without mutual exclusion.
**Fix**: Both now acquire *exclusive* (write) locks via `sync.rw_mutex_lock`. Read operations (`get_item`, `scan`, `query`) continue to use shared locks.
### delete_table item cleanup
**Bug**: `delete_table` only deleted the metadata key, leaving all data items orphaned in RocksDB.
**Fix**: Before deleting metadata, `delete_table` now iterates over all keys with the table's data prefix and deletes them individually.
### Item key type validation
**New**: `put_item` now validates that the item's key attribute types match the table's `AttributeDefinitions`. E.g., if PK is declared as `S`, putting an item with a numeric PK is rejected with `Invalid_Key`.
### Error response standardization
**Fix**: Centralized all storage-error-to-HTTP-error mapping in `handle_storage_error`. InternalServerError maps to HTTP 500; all client errors (validation, not-found, etc.) map to HTTP 400. Missing `X-Amz-Target` now returns `SerializationException` to match real DynamoDB behavior.
---
## Later (big features)
These align with the "Future Enhancements" list in ARCHITECTURE.md.
@@ -125,8 +81,8 @@ These align with the "Future Enhancements" list in ARCHITECTURE.md.
- [ ] Index backfill + write-path maintenance
### 9) Batch + transactions
- [ ] BatchWriteItem
- [ ] BatchGetItem
- [x] BatchWriteItem
- [x] BatchGetItem
- [ ] Transactions (TransactWriteItems / TransactGetItems)
### 10) Performance / ops