Commit Graph

3673 Commits

Author SHA1 Message Date
TcMits
2e7de4ccd6 parse SAVEPOINT, RELEASE 2025-08-02 15:10:41 +07:00
TcMits
6baa5abb56 parse ROLLBACK 2025-08-02 14:47:49 +07:00
TcMits
62886ee8a1 parse COMMIT|END 2025-08-02 14:32:01 +07:00
TcMits
a23500274f fix parse nm 2025-08-02 14:19:32 +07:00
TcMits
ab1b229f26 parser: compare old and new 2025-08-01 18:56:32 +07:00
TcMits
d88781340d parser: parse BEGIN... 2025-08-01 18:30:29 +07:00
TcMits
1e926d0093 parser: finish lexer and draft AST 2025-08-01 15:07:20 +07:00
Pekka Enberg
81c86d42b4 Merge 'Clean up conversion between InsnFunctionStepResult and StepResult' from Diego Reis
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2332
2025-07-30 09:11:35 +03:00
Pekka Enberg
9ab26b3ac2 Merge 'core/mvcc: simplify mvcc cursor types' from Pere Diaz Bou
We have so many cursor types that it will be unbearable to properly make
all of them work. Let's simplify this and only focus on lazy cursor
which in the future will load from database in case we need it.

Closes #2333
2025-07-30 09:10:44 +03:00
Pere Diaz Bou
caa5fe3ef4 core/mvcc: simplify mvcc cursor types
We have so many cursor types that it will be unbearable to properly make
all of them work. Let's simplify this and only focus on lazy cursor
which in the future will load from database in case we need it.
2025-07-29 20:13:52 +02:00
Diego Reis
e0b099f5ad refactor: Implement conversion between InsnFunctionStepResult and
StepResult
2025-07-29 15:02:09 -03:00
Nikita Sivukhin
841bbe3f77 add CDC types 2025-07-29 14:40:14 +04:00
Pekka Enberg
8adc807cd7 Merge 'Change function signatures to return IO Completions' from Pedro Muniz
Changes a couple of function signatures to return `Completion`. Also, I
changed `Completion` to be internally `Arc` to abstract the `Arc`
implementation detail, and to be able to attach a `#[must_use]` to the
`Completion` struct, so that cargo check can show us where we are not
tracking completions in the code. I also attached a `#[must_use]` to
`IOResult` so that we can see the places that we are not propagating or
waiting for I/O, demonstrating locations where functions should be
reentrant and are not.
Also, while we are with this refactor in progress I want to relax the
Clippy CI lint on unused_variables.

Closes #2309
2025-07-29 12:41:14 +03:00
Pekka Enberg
94e2d3a004 Merge 'perf: fix logic error in is_simple_count()' from Jussi Saurio
```
Execute `SELECT count() FROM users`/limbo_execute_select_count
                        time:   [15.635 µs 15.676 µs 15.730 µs]
                        change: [-96.011% -95.991% -95.972%] (p = 0.00 < 0.05)
                        Performance has improved.
```
Performance has improved.
Closes #2313

Closes #2314
2025-07-29 09:14:48 +03:00
Jussi Saurio
574c15b5e4 perf: fix logic error in is_simple_count() 2025-07-29 09:11:54 +03:00
pedrocarlo
3831e0db39 convert must_use compile warnings to unused_variables to track locations where we need to refactor in the future 2025-07-28 16:09:26 -03:00
pedrocarlo
d30c7d54c8 change all Arc<Completion> to Completion 2025-07-28 15:32:45 -03:00
pedrocarlo
7789c569a0 make Completion implementation contain an inner Arc<CompletionInner> so that we can must_use the Completion struct 2025-07-28 15:31:42 -03:00
pedrocarlo
617254116d begin_read_page should return completions 2025-07-28 15:31:42 -03:00
pedrocarlo
28d6245440 begin_write_btree_page should return completion 2025-07-28 15:31:42 -03:00
pedrocarlo
3104e3fee5 adjust DatabaseStorage trait to return completions 2025-07-28 15:31:42 -03:00
pedrocarlo
0088e3e1a9 must_use IOResult 2025-07-28 15:31:42 -03:00
Diego Reis
bab10909c3 Disable extension loading for wasm
We should enable it later when wasm become more mature
2025-07-28 14:49:07 -03:00
Diego Reis
0346c65a72 Fix clippy 2025-07-28 14:48:52 -03:00
Pekka Enberg
e2d4cbbe48 Merge 'core: Enforce shared database object per database file' from Pekka Enberg
We need to ensures that there is a single, shared `Database` object per
a database file. We need because it is not safe to have multiple
independent WAL files open because coordination happens at process-level
POSIX file advisory locks.
Fixes #2267

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #2299
2025-07-28 19:34:35 +03:00
Pekka Enberg
50e03ee90e core: Clean up Connection::open_with_flags()
Co-authored-by: bit-aloo <84662239+Shourya742@users.noreply.github.com>
2025-07-28 19:16:01 +03:00
Pekka Enberg
ab1a152100 core: Enforce single shared database object per database file
We need to ensures that there is a single, shared `Database` object per
a database file. We need because it is not safe to have multiple
independent WAL files open because coordination happens at process-level
POSIX file advisory locks.

Fixes #2267
Co-authored-by: ultraman <sunhuayangak47@gmail.com>
2025-07-28 19:13:53 +03:00
Pekka Enberg
9b67eb0e77 core: Fix transaction cleanup in Connection::close() 2025-07-28 19:13:53 +03:00
Pekka Enberg
5b6a30c1df core/storage: Fix B-Tree test cases to use ":memory:"
...otherwise they all share the same `Database` object.
2025-07-28 19:13:53 +03:00
Nikita Sivukhin
3614b022ab add WalInsertInfo type 2025-07-28 17:20:10 +04:00
Nikita Sivukhin
09b18f6b6e add WAL API methods to the rust bindings and extend result of wal_insert_frame method 2025-07-28 17:20:10 +04:00
Jussi Saurio
1e4e8c243a Merge 'btree/pager: Improve update performance by reusing freelist pages in allocate_page()' from Jussi Saurio
Closes #2225.
## What
We currently do not use pages in the
[freelist](https://www.sqlite.org/fileformat.html#the_freelist) at all
when allocating new pages.
## Why is this bad
The effect of this is that 1. UPDATEs with overflow pages become really
slow and 2. the database size grows really quickly. See #2225 for an
extreme example comparison with SQLite.
## The fix
Whenever `allocate_page()` is called, we first check if we have pages in
the freelist, and if we do, we recycle one of those pages instead of
creating a new one. If there are no freelist pages, we allocate a new
page as normal.
## Implementation notes
- `allocate_page()` now needs to return an `IOResult`, which means all
of its callers also need to return an `IOResult`, necessitating quite a
bit of new state machine logic to ensure re-entrancy.
- I left a few "synchronous IO hacks" in the `balance()` routine because
the size of this PR would balloon even more than it already has if I
were to fix those immediately in this PR.
- `fill_cell_payload()` uses some `unsafe` code to avoid lifetime
issues, and adds an unfortunate double-indirection via
`Arc<Mutex<Vec<T>>>` because the existing btree code constantly clones
`WriteState`, and we must ensure the underlying buffers referenced by
raw pointers in `fill_cell_payload` remain valid.
**Follow-up cleanups:**
1. remove synchronous IO hacks that would require even more state
machines and are best left for another PR
2. remove `Clone` from `WriteState` and implement it better
## Perf comparison
`main`: 33 seconds
```
jussi@Jussis-MacBook-Pro limbo % time target/release/tursodb --experimental-indexes apinatest_main.db <<'EOF'
create table t(x, y, z unique);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
EOF
Turso v0.1.3-pre.3
Enter ".help" for usage hints.
This software is ALPHA, only use for development, testing, and experimentation.
target/release/tursodb --experimental-indexes apinatest_main.db <<<''  6.81s user 21.18s system 83% cpu 33.643 total
```
PR: 13 seconds
```
jussi@Jussis-MacBook-Pro limbo % time target/release/tursodb --experimental-indexes apinatest_PR.db <<'EOF'
create table t(x, y, z unique);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
insert into t select randomblob(1024*128),randomblob(1024*128),randomblob(1024*128) from generate_series(1, 100);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
update t set x = x + 1 WHERE z > randomblob(1024*128);
EOF
Turso v0.1.3-pre.3
Enter ".help" for usage hints.
This software is ALPHA, only use for development, testing, and experimentation.

target/release/tursodb --experimental-indexes apinatest_PR.db <<<''  3.89s user 7.83s system 89% cpu 13.162 total
```
(sqlite: 2 seconds 🤡 )
---
TODO:
- [x] Fix whatever issue the simulator caught in CI (#2238 )
- [x] Post a performance comparison
- [x] Fix autovacuum test failure
- [x] Improve docs
- [x] Fix `fill_cell_payload` re-entrancy issue when allocating overflow
pages
- [x] Add proper PR description

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #2233
2025-07-28 15:30:13 +03:00
Jussi Saurio
d8a133a1a5 Merge 'VDBE/op_column: use references to cursor payload instead of cloning' from Jussi Saurio
instead use RefValue to refer to record payload directly and then copy
to register as necessary
my local:
```sql
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/1: Warming u
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/1: Collectin
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/1
                        time:   [491.64 ns 492.54 ns 493.64 ns]
                        change: [-3.6642% -3.3050% -2.9558%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  5 (5.00%) high mild
  1 (1.00%) high severe
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/10: Warming
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/10: Collecti
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/10: Analyzin
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/10
                        time:   [2.7923 µs 2.8001 µs 2.8114 µs]
                        change: [-14.643% -14.282% -13.878%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  1 (1.00%) low severe
  1 (1.00%) high mild
  4 (4.00%) high severe
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/50: Warming
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/50: Collecti
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/50: Analyzin
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/50
                        time:   [13.452 µs 13.496 µs 13.550 µs]
                        change: [-15.768% -15.471% -15.182%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) high mild
  4 (4.00%) high severe
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100: Warming
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100: Collect
Benchmarking Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100: Analyzi
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100
                        time:   [27.110 µs 27.162 µs 27.226 µs]
                        change: [-15.878% -15.604% -15.336%] (p = 0.00 < 0.05)
                        Performance has improved.
```
ci, main:
```
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100
                        time:   [70.671 µs 71.741 µs 72.910 µs]
```
ci, branch:
```
Execute `SELECT * FROM users LIMIT ?`/limbo_execute_select_rows/100
                        time:   [53.969 µs 54.013 µs 54.061 µs]
```

Reviewed-by: bit-aloo (@Shourya742)

Closes #2205
2025-07-28 14:13:54 +03:00
Pekka Enberg
aca6ffa042 Merge 'io/unix: wrap file with Mutex' from Pere Diaz Bou
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2301
2025-07-28 12:53:38 +03:00
Pere Diaz Bou
f458f622a5 io/unix: wrap file with Mutex 2025-07-28 11:33:57 +02:00
Pere Diaz Bou
752a876f9a change every Rc to Arc in schema internals 2025-07-28 10:51:17 +02:00
Pere Diaz Bou
d273de483f comment clone for schema 2025-07-28 10:50:50 +02:00
Pere Diaz Bou
6ec80b3364 clone everything in schema 2025-07-28 10:27:45 +02:00
Jussi Saurio
111c0032ae Always extend texts and blobs 2025-07-28 11:06:16 +03:00
Jussi Saurio
ae5470f1d0 use default directly 2025-07-28 11:01:26 +03:00
Jussi Saurio
12d8b266a1 Define some helper traits to reduce duplication 2025-07-28 11:01:26 +03:00
Jussi Saurio
7eb52c65d3 Add missing program counter increment 2025-07-28 11:01:26 +03:00
Jussi Saurio
b14124ad3b VDBE/op_column: avoid first cloning text/blob and then copying it again
instead use RefValue to refer to record payload directly and then copy
to register as necessary
2025-07-28 11:01:26 +03:00
Jussi Saurio
36e0ca5a9f pager: remove unnecessary LoadFreelistTrunkPage state 2025-07-28 10:11:57 +03:00
Jussi Saurio
e7b07c1357 pager: reset allocate_page_state in reset_internal_states() 2025-07-28 10:11:57 +03:00
Jussi Saurio
c349a9d689 Ensure underlying payload vec cannot be copied so that raw pointers remain valid 2025-07-28 10:11:57 +03:00
Pekka Enberg
fd2a7f9098 core: Switch to unreachable for invalid enum variants
The parser unfortunately outputs Stmt, which has some enum variants that
we never actually encounter in some parts of the core. Switch to
unreachable instead of todo.
2025-07-28 09:52:20 +03:00
Jussi Saurio
08d5b3b4bc btree: make fill_cell_payload() re-entrant (overflow pages may require IO) 2025-07-28 09:00:59 +03:00
Jussi Saurio
927aca7857 Fix incorrect autovacuum test 2025-07-28 09:00:59 +03:00
Jussi Saurio
e2e25a48f6 Pager: document origins of BtreePageAllocMode 2025-07-28 09:00:59 +03:00