Commit Graph

614 Commits

Author SHA1 Message Date
Jussi Saurio
0eeabbb748 Merge 'btree/chore: remove unnecessary parameters to .cell_get()' from Jussi Saurio
we were providing the same damn arguments to `.cell_get()` and
`.cell_get_raw_region()` over and OVER and **OVER** and `O V E R`

Reviewed-by: Preston Thorpe (@PThorpe92)

Closes #2021
2025-07-10 12:22:37 +03:00
Jussi Saurio
c2b699c356 btree: make cell field names consistent 2025-07-09 23:43:03 +03:00
Jussi Saurio
641df7d7e9 improve my mental health by finally refactoring .cell_get() 2025-07-09 19:15:05 +03:00
meteorgan
0001348158 Minor refactoring of btree 2025-07-09 22:01:54 +08:00
Jussi Saurio
11d4489740 Merge 'sqlite3_ondisk: generalize left-child-pointer reading function to both index/table btrees' from Jussi Saurio
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #2015
2025-07-09 14:24:08 +03:00
Jussi Saurio
c752058a97 VDBE: introduce state machine for op_idx_insert for more granular IO control
Separates cursor.key_exists_in_index() into a state machine. The problem with
the main branch implementation is this:

`return_if_io!(seek)`
`return_if_io!(cursor.record())`

The latter may yield on IO and cause the seek to start over, causing an infinite
loop. With an explicit state machine we can control and prevent this.
2025-07-09 11:43:18 +03:00
Jussi Saurio
c13b2d5d90 sqlite3_ondisk: generalize left-child-pointer reading function to both index/table btrees 2025-07-09 11:07:42 +03:00
meteorgan
99e0cf0603 add a constant MINIMUM_CELL_SIZE 2025-07-08 22:57:20 +08:00
meteorgan
04575456a9 fix Minimum cell size must not be less than 4 2025-07-08 22:57:20 +08:00
Jussi Saurio
3ab5f07389 btree: fix incorrect comparison implementation in key_exists_in_index()
1. current implementation did not use the custom PartialOrd implementation
   for RefValue
2. current implementation did not take collation into account
2025-07-08 11:58:57 +03:00
Pekka Enberg
1907df825c Merge 'Use binary search in find_cell()' from Ihor Andrianov
Find cell using  bin search

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

Closes #1875
2025-07-08 10:22:26 +03:00
pedrocarlo
b85687658d change instrumentation level to INFO 2025-07-07 11:53:45 -03:00
pedrocarlo
7c10ac01e6 do_allocate_page should return a Result 2025-07-07 11:53:45 -03:00
pedrocarlo
5559c45011 more instrumentation + write counter should decrement if pwrite fails 2025-07-07 11:50:21 -03:00
pedrocarlo
897426a662 add error tracing to relevant functions + rollback transaction in step_end_write_txn + make move_to_root return result 2025-07-07 11:50:21 -03:00
pedrocarlo
db005c81a0 add option to disable wal checkpoint 2025-07-03 12:04:17 -03:00
Ihor Andrianov
650c85ccd7 save binary search state for reentrant execution 2025-07-03 15:08:16 +03:00
Pekka Enberg
90e035b6b0 Merge 'Rollback schema support' from Pere Diaz Bou
Fixes #1890
Once rollback was implement we quickly saw that it lacked support for
schema changes so we had to re-estructure things a bit.
## Example of failure:
```bash
turso> begin;
turso> create table t(x);
turso> rollback;
turso> pragma integrity_check;
thread 'main' panicked at core/storage/sqlite3_ondisk.rs:386:36:
called `Result::unwrap()` on an `Err` value: Corrupt("Invalid page type: 83")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
This happened because it thought table `t` existed because we didn't
rollback that schema.
## Changes:
* The most important change: now every connection has a private copy of
schema. On write txn commit we update a global schema shared between
connections in order for new connections to get updated version from
there. In case of rollback, we simply change connection's schema to
previous version. This change allowed us to remove locks for schema
private copy and keeping schema changes locally in case of concurrency.
 Sqlite does things differently, they lazily parse schema in case of
outdated schema, this many schema changes to trigger reading schema from
db file which is slow. If we are able to keep local copy in memory, even
when if we add multiprocessing, it will speed up schema reloading by a
bunch.
* `schema_cookie` is now update for every schema change
* `Insn::ParseSchema` had a nasty bug where it would commit all the
changes made in a query that changed a schema, we fixed that by setting
`auto_commit` to `false` before parsing schema, and setting it back to
previous value once schema is parsed.

Closes #1928
2025-07-03 14:18:00 +03:00
Pere Diaz Bou
abf1699dd2 set scheam version and update shared schema in txn 2025-07-03 12:36:48 +02:00
Pekka Enberg
fa442ecd6e core/storage: Switch to turso_assert in btree.rs
Let's help out Antithesis to find interesting bugs.
2025-07-03 13:25:13 +03:00
KaguraMilet
f339e9c1ad fix integrity check error 2025-07-03 13:47:30 +08:00
KaguraMilet
aca08238d8 fix buffer pool is not thread safe problem 2025-07-01 16:06:55 +08:00
Pekka Enberg
9c1b7897ac Fix URLs to point to github.com/tursodatabase/turso 2025-06-30 11:23:53 +03:00
Ihor Andrianov
40c14f705f fix equal handling 2025-06-28 19:51:23 +03:00
Ihor Andrianov
8942bb7474 make find_cell use binary search 2025-06-28 18:53:44 +03:00
pedrocarlo
bac5e4b563 refactor File and Database Storage to remove Arc<Connection> and return Arc<Connection> for caller to wait for completion 2025-06-26 22:17:28 -03:00
pedrocarlo
64d9193e7b refactor Completion to have a type field and lift common is_complete property 2025-06-26 22:17:27 -03:00
Pekka Enberg
572c722390 Merge 'write page1 on database initialization' from Pere Diaz Bou
Page 1 must be initialized and written as soon as possible without
marking page as dirty.
OpenEphemeral now requires a state machine to accomodate new
begin_write_tx semantics.

Closes #1839
2025-06-26 20:43:40 +03:00
Pere Diaz Bou
e341b80051 clippy 2025-06-26 15:01:54 +02:00
Pere Diaz Bou
4d80b8237d write page1 on database initialization
Page 1 must be initialized and written as soon as possible without
marking page as dirty.
2025-06-26 14:44:23 +02:00
Pekka Enberg
2fc5c0ce5c Switch to runtime flag for enabling indexes
Makes it easier to test the feature:

```
$ cargo run --  --experimental-indexes
Limbo v0.0.22
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database
limbo> CREATE TABLE t(x);
limbo> CREATE INDEX t_idx ON t(x);
limbo> DROP INDEX t_idx;
```
2025-06-26 10:07:28 +03:00
Pekka Enberg
a48198ec60 Merge 'Rollback simple support' from Pere Diaz Bou
Support for simple interactive rollback like:
```sql
    create table t (x);
    insert into t values (1);
    begin;
    insert into t values (2);
    rollback;
    select * from t;
```
This PR also fixes some other issues I found while debugging:
* Checkpoint would never `clear_dirty` on pages in page cache.
* Auto commit for interactive transactions was not respected so any
`insert` after `begin` would flush frames regardless of `auto_commit`
state.
* `max_frame` on wal shared state was being updated after every
`append_frame` which was incorrect, as another transaction would be able
to use that new `max_frame` even tho the transaction could've rolled
back. Instead we update the private copy of `max_frame` and only update
it at the end.
Follow up for later are savepoints which require implementing a
subjournal to track savepoints and their modified pages.

Closes #1825
2025-06-25 20:02:09 +03:00
Pere Diaz Bou
0119b0f99d clippy 2025-06-25 14:01:53 +02:00
Pere Diaz Bou
22f9cd695d commit_txn track rollback case 2025-06-25 14:00:57 +02:00
Jussi Saurio
27b3ecf599 core/db&pager: fix locking for initializing empty database
When `struct Database` is constructed, store `is_empty` as an
`Arc<AtomicBool>` - the value is true if:

1. DB size is zero
2. WAL has no frames

When `struct Pager` is constructed, this `Arc` is simply cloned.
When any connection runs a transaction it will first check `is_empty`,
and if the DB is empty, it will lock `init_lock` and then check `is_empty`
again, and if it's still true, it allocates page1 and stores `false` in
the `is_empty` `AtomicBool` and drops the lock.

---

Note that Limbo can currently have a zero DB and a WAL with frames,
as we have no special logic for folding page1 to the main DB file
during initialization.

Page 1 allocation currently happens on the first transaction (read or
write, due to having to support `select * from sqlite_schema` on an
empty DB; we should really check how SQLite actually does this.).
2025-06-25 14:45:21 +03:00
Jussi Saurio
133d498724 Implement a header_accessor module so that DatabaseHeader structs arent initialized on every access 2025-06-24 14:41:50 -03:00
Jussi Saurio
acafe71d9e Dont allocate fresh page1 if it's in the WAL 2025-06-24 14:41:50 -03:00
Jussi Saurio
cc2e14b11c Read page 1 from pager always, no separate db_header 2025-06-24 14:41:49 -03:00
Jussi Saurio
bdfbb8fe54 Fix erroneous early return 2025-06-24 11:26:00 +03:00
Jussi Saurio
5878724d0e fix/btree: balance and seek after overwritten cell overflows 2025-06-24 11:08:22 +03:00
Nils Koch
2827b86917 chore: fix clippy warnings 2025-06-23 19:52:13 +01:00
pedrocarlo
74beac5ea8 ephemeral table for update when rowid is being update 2025-06-20 16:28:10 -03:00
Pere Diaz Bou
34592b172c run index tests with flags instead of ignore 2025-06-17 19:33:23 +02:00
Pekka Enberg
4496a0d08a core: Clean up integrity_check()
Suggested by Jussi.
2025-06-16 14:46:36 +03:00
Pekka Enberg
882c5ca168 Merge 'Simple integrity check on btree' from Pere Diaz Bou
This PR adds support for the instruction `IntegrityCk` which performs an
integrity check on the contents of a single table. Next PR I will try to
implement the rest of the integrity check where we would check indexes
containt correct amount of data and some more.
<img width="1151" alt="image" src="https://github.com/user-
attachments/assets/29d54148-55ba-480f-b972-e38587f0a483" />

Closes #1719
2025-06-16 13:46:26 +03:00
Pekka Enberg
90c1e3fc06 Switch Connection to use Arc instead of Rc
Connection needs to be Arc so that bindings can wrap it with `Mutex` for
multi-threading.
2025-06-16 10:43:19 +03:00
pedrocarlo
8dbf09bb42 betters instrumentation for btree operations 2025-06-11 23:34:32 -03:00
Pere Diaz Bou
9edbfa436a fmt again 2025-06-11 19:12:19 +02:00
Pere Diaz Bou
3f3e91927f fmt 2025-06-11 19:02:23 +02:00
Pere Diaz Bou
a24e1b775c check order of rowids 2025-06-11 17:56:19 +02:00