We previously were making another inline completion inside io_uring.rs,
I thought this wouldn't be needed anymore because of the Arc that is now
wrapping the RefCell<Buffer>, but in the case of the WAL header, where
it's not pinned to a page in the cache, there is nothing to keep it
alive and we will write a corrupt wal header.
```rust
#[allow(clippy::arc_with_non_send_sync)]
Arc::new(RefCell::new(buffer))
};
let write_complete = move |bytes_written: i32| {
turso_assert!(
bytes_written == WAL_HEADER_SIZE as i32,
"wal header wrote({bytes_written}) != expected({WAL_HEADER_SIZE})"
);
};
// buffer is never referenced again, this works for sync IO but io_uring writes junk bytes
```
<img width="881" height="134" alt="image" src="https://github.com/user-
attachments/assets/0ff06ad5-411a-43d2-abac-caf9e23ceaeb" />
Closes#2297
### Follow SUM [spec](https://sqlite.org/lang_aggfunc.html)
This PR updates the `SUM` aggregation logic to follow the
[Kahan–Babushka–Neumaier summation
algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm),
consistent with SQLite’s implementation. It improves the numerical
stability of floating-point summation.This fixes issue #2252 . I added a
fuzz test to ensure the compatibility of the implementations
I also fixed the return types for `SUM` to match SQLite’s documented
behavior. This was previously discussed in
[#2182](https://github.com/tursodatabase/turso/pull/2182), but part of
the logic was later unintentionally overwritten by
[#2265](https://github.com/tursodatabase/turso/pull/2265).
I introduced two helper functions, `apply_kbn_step` and
`apply_kbn_step_int`, in `vbde/execute.rs` to handle floating-point and
integer accumulation respectively. However, I’m new to this codebase and
would welcome constructive feedback on whether there’s a better place
for these helpers.
Reviewed-by: Preston Thorpe (@PThorpe92)
Closes#2270
I know I have #2179 and now #2278 open both working on checkpointing,
but I discovered during async IO benchmarks that once we hit
`should_checkpoint` (there are greater than 1000 frames in the WAL), we
will trigger checkpoint on cache flush every single write, and since we
don't update `nbackfills` in the case that everything was backfilled,
every checkpoint will backfill every single frame to the db file 💀
At least this can be reviewed+merged faster and easier.
This also fixes the return value of `pragma wal_checkpoint;` to match
sqlite.
Sqlite returns the # of possible frames (`shared.max_frame -
shared.nbackfills`, and then the number of frames we successfully
checkpointed `ongoing_checkpoint.max_frame -
ongoing_checkpoint.min_frame + 1`)
If `pragma wal_checkpoint;` is called again when there are no pages to
backfill, then it returns the value from the previous checkpoint.
<img width="781" height="293" alt="image" src="https://github.com/user-
attachments/assets/9aa78a6c-aa18-444d-82bd-398d684fed75" />
Closes#2280
we would encounter a panic in `display.rs` when a column name does not
exist.
```
turso> select * from (select 1);
thread 'main' panicked at core/translate/display.rs:252:50:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
after this PR:
```
turso> select * from (select 1);
2025-07-25T15:52:24.241294Z DEBUG ThreadId(01) run_cmd:translate:optimize_plan: turso_core::translate::optimizer: 51: plan_sql="SELECT subquery_0.0 FROM (SELECT 1 FROM) AS subquery_0"
2025-07-25T15:52:24.242036Z DEBUG ThreadId(01) step:begin_read_tx:begin_read_tx: turso_core::storage::wal: 552: begin_read_tx(min_frame=1, max_frame=0, lock=0, max_frame_in_wal=0)
2025-07-25T15:52:24.242349Z DEBUG ThreadId(01) step:commit_txn:end_read_tx:end_read_tx: turso_core::storage::wal: 566: end_read_tx(lock=0)
┌───┐
│ . │
├───┤
│ 1 │
└───┘
```
Closes#2269
Switch to napi [v3](https://napi.rs/blog/announce-v3).
With the exception of `Statement.iterate()`, the behavior is preserved.
I had to temporarily remove it because the trait `Generator` doesn't
supports the new lifetime scoped values, I already brought this issue in
napi's discord server and it should be fixed soon.
Closes#2262
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/penberg/src/tursodatabase/turso/packages/turso-serverless/dist/error' imported from /Users/penberg/src/tursodatabase/turso/packages/turso-serverless/dist/protocol.js
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/penberg/src/tursodatabase/turso/packages/turso-serverless/dist/error' imported from /Users/penberg/src/tursodatabase/turso/packages/turso-serverless/dist/protocol.js
at finalizeResolution (node:internal/modules/esm/resolve:275:11)
at moduleResolve (node:internal/modules/esm/resolve:860:10)
at defaultResolve (node:internal/modules/esm/resolve:984:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:780:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:704:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:687:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:305:38)
at ModuleJob._link (node:internal/modules/esm/module_job:137:49)
✘ integration-tests/serverless.test.mjs exited with a non-zero exit code: 1
```