Commit graph

496 commits

Author SHA1 Message Date
Nikita Sivukhin
8cc40949a5 fix clippy 2025-12-10 15:08:44 +04:00
Nikita Sivukhin
e70428e976 add explicit insert action to the fuzz test and disable it for now 2025-12-10 14:53:32 +04:00
Nikita Sivukhin
70b1e5716d add fuzz test which maintain sqlite3 and turso db and periodically switch them between each other in order to validate compatibility 2025-12-10 14:53:32 +04:00
Nikita Sivukhin
9acf541e28 add compatibility test for multiple-columns unique constraint 2025-12-10 01:46:25 +04:00
Jussi Saurio
2aefb4ee8c
Merge 'fix/btree: disable move_to_rightmost optimization with triggers' from Jussi Saurio
Some checks are pending
Build & publish @tursodatabase/database / db-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-apple-darwin - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-wasm32-wasip1-threads - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / Test DB bindings on Linux-x64-gnu - node@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Test DB bindings on browser@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Publish (push) Blocked by required conditions
Python / configure-strategy (push) Waiting to run
Python / test (push) Blocked by required conditions
Python / lint (push) Waiting to run
Python / linux (x86_64) (push) Waiting to run
Python / macos-arm64 (aarch64) (push) Waiting to run
Python / sdist (push) Waiting to run
Python / Release (push) Blocked by required conditions
Rust / cargo-fmt-check (push) Waiting to run
Rust / build-native (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Rust / build-native (macos-latest) (push) Waiting to run
Rust / build-native (windows-latest) (push) Waiting to run
Rust / clippy (push) Waiting to run
Rust / simulator (push) Waiting to run
Rust / test-limbo (push) Waiting to run
Rust / test-sqlite (push) Waiting to run
Rust Benchmarks+Nyrkiö / bench (push) Waiting to run
Rust Benchmarks+Nyrkiö / clickbench (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h-criterion (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h (push) Waiting to run
Rust Benchmarks+Nyrkiö / vfs-bench-compile (push) Waiting to run
## Closes
- Closes #4017
- Addresses #4043; this now fails with `Page cache is full` with 100k
pages, which is a separate non-corruption issue. Modifying max page
cache size to be 10 million pages makes it not finish at all. We should
modify the issue after this is merged to reflect what the new problem
is. The queries in the issue (#4043) create a WAL that is at least 1.7
GB in size
## Background
We have an optimization in the btree where if:
- We want to reach the rightmost leaf page, and
- We know the rightmost page and are already on it
Then we can skip a seek.
## Problem
The problem is this optimization should NEVER be used in cases where we
cannot be sure that the btree wasn't modified from under us e.g. by a
trigger subprogram.
## Fix
Hence, disable it when we are executing a parent program that has
triggers which will fire.
## AI Disclosure
No AI was used for this PR.

Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #4135
2025-12-09 10:02:11 +02:00
Jussi Saurio
2e8b771f6f
Merge 'Fix descending index scan returning rows when seek key is NULL' from Jussi Saurio
Closes #4066
Closes #4129
## Problem
Take e.g.
CREATE TABLE t(x); CREATE INDEX txdesc ON t(x desc); INSERT INTO t
values (1),(2),(3);
SELECT * FROM t WHERE x > NULL;
--
Our plan, like Sqlite, was to start iterating the descending index from
the beginning (Rewind) and stop once we hit a row where x is <= than
NULL using `IdxGe` instruction (GE in descending indexes means LE).
However, `IdxGe` and other similar instructions use a sort comparison
where NULL is less than numbers/strings etc, so this would incorrectly
not jump.
## Fix
Fix: we need to emit an explicit NULL check after rewinding.
## Tests
Added TCL tests + improved `index_scan_compound_key_fuzz` to have NULL
seek keys sometimes.
## AI disclosure
I started debugging this with Claude Code thinking this is a much deeper
corruption issue, but Opus 4.5 noticed immediately that we are returning
rows from a `x > NULL` comparison which should never happen. Hence, the
fix was then fairly simple.

Closes #4132
2025-12-09 09:38:18 +02:00
Jussi Saurio
201a7e6387 Regression test for 4017 2025-12-09 09:19:37 +02:00
Nikita Sivukhin
997a07cac9 add test with concurrent commit/rollback and insert stmt 2025-12-08 16:34:07 +04:00
Jussi Saurio
027ebe33fe Fix descending index scan returning rows when seek key is NULL
Take e.g.

CREATE TABLE t(x); CREATE INDEX txdesc ON t(x desc);
INSERT INTO t values (1),(2),(3);

SELECT * FROM t WHERE x > NULL;

--

Our plan, like Sqlite, was to start iterating the descending index
from the beginning (Rewind) and stop once we hit a row where x is
<= than NULL using `IdxGe` instruction (GE in descending indexes
means LE).

However, `IdxGe` and other similar instructions use a sort comparison
where NULL is less than numbers/strings etc, so this would incorrectly
not jump.

Fix: we need to emit an explicit NULL check after rewinding.
2025-12-08 13:19:58 +02:00
Jussi Saurio
826ca4d44d chore: remove experimental_indexes feature flags 2025-12-08 13:00:37 +02:00
Preston Thorpe
c09c30746e
Merge 'guard subjournal access within single connection' from Nikita Sivukhin
Right now turso can panic with various asserts if 2 or more write
statements will be executed over single connection concurrently:
```
thread 'query_processing::test_write_path::api_misuse' panicked at core/storage/pager.rs:776:9:
subjournal offset should be 0
```
This PR adds explicit guard for subjournal access which will return
`Busy` for the operation internally and lead to wait condition for the
statement until subjournal ownership will be released and can be re-
acquired again.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #4110
2025-12-05 13:14:07 -05:00
Preston Thorpe
e7c7f232b4
Merge 'testing/fuzz: Add new fuzzer for joins' from Preston Thorpe
needed for #4063 to merge, currently passing on main but just want to
lower the already huge diff

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #4103
2025-12-05 13:13:44 -05:00
Nikita Sivukhin
659ef7c079 fix clippy 2025-12-05 21:39:35 +04:00
Nikita Sivukhin
487854e6d6 guard subjournal access in order to prevent concurrent operations over it within same connection 2025-12-05 21:25:13 +04:00
PThorpe92
c9a6827011
Extract out join fuzzer to an additional test on indexed columns 2025-12-05 12:03:23 -05:00
Jussi Saurio
a90087bcf6 Enable compound_select_fuzz for mvcc because it works as a regression test for #4108 2025-12-05 17:19:05 +02:00
Nikita Sivukhin
d5f58de801 fix clippy 2025-12-05 15:29:17 +04:00
Nikita Sivukhin
e839eb499b make fuzzer to generate SELECT COUNT(*) OR SELECT * statements
- this is important for IN operation translation bug because in case of COUNT(*) there is constant assignment instruction right after last instruction translated from IN condition
2025-12-05 14:48:59 +04:00
Jussi Saurio
eb782ce2d4 fix/mvcc: seek() must seek from both mv store and btree
for example, upon opening an existing database, all the rows are in
the btree, so if we seek only from MV store, we won't find anything.
ergo: we must look from both the mv store and the btree. if we are
iterating forwards, the smallest of the two results is where we land,
and vice versa for backwards iteration.

initially this implementation used blocking IO but was refactored to
use state machines after the rest of the Cursor methods in the MVCC cursor
module were refactored to do that too.

---

this PR was initially almost entirely written using Claude Code + Opus 4.5,
but heavily manually cleaned up as the AI made the state machine refactor
far too complicated.
2025-12-05 11:53:16 +02:00
PThorpe92
16a1940d3a
Reduce iteration count in join fuzzer to 2000 2025-12-04 16:23:46 -05:00
PThorpe92
bf6038f0ba
Add join fuzzer for non-indexed columns 2025-12-04 16:19:19 -05:00
Jussi Saurio
3eccee731e Remove todo comment from test 2025-12-03 16:32:20 +02:00
Jussi Saurio
fd067912dc tests/fuzz/mvcc: enable table_index_mutation_fuzz for mvcc
special cases: do not use triggers or expression indexes for the
mvcc version of the test.
2025-12-03 16:28:53 +02:00
Jussi Saurio
3b412f9b02 mvcc: commit index rows and recover them from logical log
also adds tests
2025-12-02 11:38:05 +02:00
Jussi Saurio
ea905d276c
Merge 'Add #[turso_macros::test] to automatically create tests that can run MVCC with minimal code changes' from Pedro Muniz
- added procedural macro that creates Rust tests and with just a flag,
creates a new test that runs the same with MVCC enabled
- migrated almost all tests to use this new macro and added the mvcc
flag to the tests that were not failing
- added a `TempDatabase` builder to facilitate the proc_macro to
generate the correct database options

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #3991
2025-11-27 21:53:09 +02:00
Jussi Saurio
e5937de219 mvcc: reconstruct index rows on logical log recovery
index rows are not committed to the logical log, so we derive them
after recovery and insert them to the mv store.
2025-11-27 20:35:49 +02:00
PThorpe92
9223dfdbff
Add integration test to ensure covering expr index is used 2025-11-20 12:47:50 -05:00
PThorpe92
2688f8b9c3
Add tcl tests for expr indexes and collation 2025-11-20 12:47:49 -05:00
PThorpe92
b0ac042092
Add tests for using expr indexes in query plans for ORDER BY and WHERE predicates 2025-11-20 12:47:47 -05:00
PThorpe92
04629d4d7b
Add some expression indexes in our fuzz tests 2025-11-20 12:47:46 -05:00
pedrocarlo
2ef2b13278 pending byte page cannot run at the same time with mvcc test 2025-11-19 23:52:22 -03:00
pedrocarlo
a3acec58df clippy 2025-11-19 23:42:46 -03:00
pedrocarlo
963b37f6ee change fuzz test to use new test macros 2025-11-19 23:28:23 -03:00
pedrocarlo
8b2caab3cc change pragma test to use new test macros 2025-11-19 23:28:23 -03:00
pedrocarlo
5aed5147c9 change trigger test to use new test macros 2025-11-19 23:28:23 -03:00
pedrocarlo
c4653ae34c change functions to use new test macros 2025-11-19 23:28:23 -03:00
pedrocarlo
479048ee99 change index_methods to use new test macros 2025-11-19 23:28:23 -03:00
pedrocarlo
4a79d4f5d4 change encryption to use new test macros 2025-11-19 14:47:13 -03:00
pedrocarlo
3bc0499f97 change test_btree to use new test macros 2025-11-19 13:46:48 -03:00
pedrocarlo
789532688e change test_ddl to use new test macros 2025-11-19 13:30:35 -03:00
pedrocarlo
c58cd32eee change test_multi_thread to use new test macros 2025-11-19 13:30:05 -03:00
pedrocarlo
5301a042d9 change test_read_path to use new test macros 2025-11-19 13:30:05 -03:00
pedrocarlo
f3854c2db2 change test_transactions to use new test macros 2025-11-19 12:28:37 -03:00
pedrocarlo
39ffa76c28 change test_write_path to use new test macros 2025-11-19 12:08:48 -03:00
pedrocarlo
463ca00004 migrate test cases to use the macro 2025-11-19 12:08:18 -03:00
pedrocarlo
0ffda31549 add init_sql arg to proc macro 2025-11-19 12:08:18 -03:00
pedrocarlo
91e1fc45fa create temp database builder to facilitate passing options to proc macro 2025-11-19 12:08:18 -03:00
pedrocarlo
1e85706d54 pass the fn arg type to the macro closure to avoid errors 2025-11-19 11:49:53 -03:00
pedrocarlo
237ce5b601 enhance proc macro to detect the fn args and the return type with better spans 2025-11-19 11:49:53 -03:00
pedrocarlo
696bf2252c create a basic test proc macro that takes a db path and an mvcc flag 2025-11-19 11:49:53 -03:00