Commit Graph

7147 Commits

Author SHA1 Message Date
bit-aloo
c7f7ae32e3 review fixes 2025-08-08 08:43:15 +05:30
bit-aloo
6ffd4215a2 sort Pragma names in lexicographical order 2025-08-08 02:52:45 +05:30
bit-aloo
ee483ce4e9 update compat.md with query_only pragma 2025-08-07 23:50:18 +05:30
bit-aloo
aaeec4d4f3 Implement PRAGMA query_only logic 2025-08-07 23:49:07 +05:30
bit-aloo
2cf7f66a02 Enforce query_only in write operations 2025-08-07 23:46:00 +05:30
bit-aloo
ef084af42f Add getter and setter methods 2025-08-07 23:44:54 +05:30
bit-aloo
697eb35ca9 Add query_only field to Connection 2025-08-07 23:44:29 +05:30
Jussi Saurio
fc95282c57 Merge 'core/btree: fix re-entrancy bug in insert_into_page()' from Jussi Saurio
## Background
We currently clone `WriteState` on every iteration of
`insert_into_page()`,
presumably for _Borrow Checker Reasons (tm)_.
## Problem
There was a bug in `WriteState::Insert` handling where if
`fill_cell_payload()`
returned IO, the `fill_cell_payload_state` was not updated in
`write_info.state`, leading to an infinite loop of allocating new pages.
Further, the `new_payload` vector was also always deep-cloned.
## Fix
Update the state if `fill_cell_payload()` returns IO. Because of
`WriteState` cloning we also need to `Arc<Mutex>` wrap the vector so
that the underlying data buffer doesn't get cloned the next time
`WriteState` gets cloned, since `fill_cell_payload` relies on raw
pointers to work. Left a couple of prominent FIXMEs about this.
## Notes
This bug was surfaced by, but not caused by,
https://github.com/tursodatabase/turso/pull/2400.

Closes #2463
2025-08-06 08:23:49 +03:00
Jussi Saurio
839d428e36 core/btree: fix re-entrancy bug in insert_into_page()
We currently clone WriteState on every iteration of `insert_into_page()`,
presumably for Borrow Checker Reasons (tm).

There was a bug in `WriteState::Insert` handling where if `fill_cell_payload()`
returned IO, the `fill_cell_payload_state` was not updated in
`write_info.state`, leading to an infinite loop of allocating new pages.

This bug was surfaced by, but not caused by, #2400.
2025-08-06 08:01:49 +03:00
Jussi Saurio
cd3fe523a3 core/types: add IOResult::is_io() helper 2025-08-06 07:46:51 +03:00
PThorpe92
f6fb786cc9 Fix borrow method on WindowsIO 2025-08-05 22:26:19 -04:00
Preston Thorpe
cb9a74ccc6 Merge 'Remove RefCell from Buffer in IO trait methods and PageContents' from Preston Thorpe
We are doing unsafe mut borrowing in `PageContent` currently, and when
new BufferPool is merged, it will be all pointers into an arena anyway.
We just need to be sure to clone the Arc and reference the buffers in
the completion callbacks so they are ensured to live for async IO.
naturally in true spirit of all my previous PR's, I needed to introduce
one while another is open that causes an absurd amount of conflicts.

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

Closes #2456
2025-08-05 21:30:27 -04:00
PThorpe92
4010c7bf0b Make clippy happy 2025-08-05 21:24:54 -04:00
PThorpe92
53a0524050 Fix clippy warning 2025-08-05 16:24:50 -04:00
PThorpe92
f6a68cffc2 Remove RefCell from IO and Page apis 2025-08-05 16:24:49 -04:00
Preston Thorpe
01531be9f4 Merge 'Remove Clone impl for Buffer and PageContent' from Preston Thorpe
After #2258, we no longer need to clone/deep copy `PageContent` or
`Buffer`.
We can remove the implementation to make any copying of page data
explicit.

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

Closes #2453
2025-08-05 16:17:13 -04:00
PThorpe92
914c10e095 Remove Clone impl for Buffer and PageContent 2025-08-05 14:26:53 -04:00
Pekka Enberg
9492a29d47 Merge 'Fix performance regression' from Jussi Saurio
Closes #2440
## Fix 1
Do not start a read transaction when a SELECT is not going to access the
database, which means we can avoid checking whether the schema has
changed.
## Fix 2
Add a field `accesses_db` to `Program` and `Statement` so we can avoid
even checking for `SchemaUpdated` errors when it's not possible to get
one.
## Fix 3
Avoid doing any work in `commit_txn` when not in a transaction. This
optimization is only enabled when `mv_store.is_none()`, because MVCC has
its own logic and this doesn't work with MVCC enabled, and honestly I'm
too tired to find out why. Left an inline comment about it, though.
```sql
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [21.440 ns 21.513 ns 21.586 ns]
                        change: [-60.766% -60.616% -60.453%] (p = 0.00 < 0.05)
                        Performance has improved.
```
Effect is even more dramatic in CI where the latency is down over 80%

Closes #2441
2025-08-05 16:30:18 +03:00
Jussi Saurio
cde8567b1d Merge 'More state machine + Return IO in places where completions are created' from Pedro Muniz
In preparation for tracking IO Completions, we need to start to return
IO in places where completions are created. Doing some more plumbing now
to avoid bigger PRs for the future

Closes #2438
2025-08-05 15:47:51 +03:00
Jussi Saurio
d13a1a0eec Merge 'test/fuzz: add ALTER TABLE column ops to tx isolation fuzz test' from Jussi Saurio
## Beef
Adds `AddColumn`, `DropColumn`, `RenameColumn`
## Details
- Previously the test was hardcoded to assume there's always 2 named
columns, so changed a bunch of things for this reason
- Still assumes the primary key column is always `id` and is never
renamed or dropped etc.

Closes #2434
2025-08-05 15:42:31 +03:00
Pekka Enberg
49123db6e8 Merge 'core/mvcc: implement exists' from Pere Diaz Bou
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2446
2025-08-05 15:34:23 +03:00
Jussi Saurio
9f820ae4c7 Merge 'cleanup: remove unused page uptodate flag' from Jussi Saurio
Closes #2445
2025-08-05 15:26:41 +03:00
Jussi Saurio
1feb5ba2d3 perf/vdbe: avoid doing work in commit_txn if not in txn 2025-08-05 15:25:28 +03:00
Jussi Saurio
3f633247f7 perf/stmt: avoid checking for SchemaUpdated errors if it's impossible 2025-08-05 15:10:55 +03:00
Jussi Saurio
c498196c7b fix/perf: fix regression in SELECT 1 benchmark
Do not start a read transaction when a SELECT is not going to access
the database, which means we can avoid checking whether the schema has
changed.
2025-08-05 15:10:55 +03:00
Pere Diaz Bou
474f0d8bbc core/mvcc: implement exists 2025-08-05 13:34:51 +02:00
Jussi Saurio
a28e64bfdd cleanup: remove unused page uptodate flag 2025-08-05 14:25:42 +03:00
Pere Diaz Bou
a3cf3051d7 Merge 'tests/fuzz_transactions: add tests for fuzzing transactions with MVCC' from Pere Diaz Bou
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2444
2025-08-05 13:18:57 +02:00
Pekka Enberg
d2fea25fef Merge 'perf/btree: implement fast algorithm for defragment_page' from Jussi Saurio
Implement sqlite's fast path defragment algorithm. This path is taken
when:
1. There are 1-2 freeblocks
2. There are at most `max_frag_bytes` fragmented free bytes (-1..=4)
Instead of reconstructing the entire page, it merges the two freeblocks
and then moves the merged freeblock to the left, effectively turning it
into free space in the unallocated region, instead of a freeblock.
`max_frag_bytes` is particularly important when jnserting a new cell,
because if the page contains (in total) ~just enough space for the new
cell, then there can be hardly any fragmented free space because
otherwise, merging the 1-2 freeblocks won't produce enough contiguous
free space to fit the cell.
## Benchmark
```sql
Insert rows in batches/limbo_insert_1_rows
                        time:   [26.692 µs 27.153 µs 27.695 µs]
                        change: [-9.9033% -2.9097% +1.6336%] (p = 0.55 > 0.05)
                        No change in performance detected.
Insert rows in batches/limbo_insert_10_rows
                        time:   [38.618 µs 40.022 µs 42.201 µs]
                        change: [-8.9137% -6.6405% -4.2299%] (p = 0.00 < 0.05)
                        Performance has improved.
Insert rows in batches/limbo_insert_100_rows
                        time:   [168.94 µs 169.58 µs 170.31 µs]
                        change: [-22.520% -17.669% -12.790%] (p = 0.00 < 0.05)
                        Performance has improved.
```

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

Closes #2411
2025-08-05 12:44:48 +03:00
Pekka Enberg
aa20c2f1ba Merge 'Relax I/O configuration attribute to cover all Unixes' from Pedro Muniz
hopefully fixes #2268.

Closes #2435
2025-08-05 12:44:34 +03:00
Pere Diaz Bou
2a3e2349ca tests/fuzz_transactions: add tests for fuzzing transactions with MVCC 2025-08-05 11:43:26 +02:00
Pekka Enberg
a972b81a39 Merge 'bindings/rust: add with_mvcc option, open with path too!' from Pere Diaz Bou
Closes #2443
2025-08-05 12:42:30 +03:00
Pekka Enberg
e355fc4c65 Merge 'core/mvcc: implement seeking operations with rowid' from Pere Diaz Bou
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2429
2025-08-05 12:40:48 +03:00
Pekka Enberg
d9fd56c31f Merge 'bindings/rust: add with_mvcc option' from Pere Diaz Bou
Closes #2442
2025-08-05 12:40:34 +03:00
Pere Diaz Bou
2392ea1b55 bindings/rust: add with_mvcc option 2025-08-05 11:40:23 +02:00
Pere Diaz Bou
e5fc08317a bindings/rust: add with_mvcc option 2025-08-05 11:28:36 +02:00
Jussi Saurio
ad35cf07eb Add extra illustrative doodle for pere 2025-08-05 11:24:15 +03:00
Jussi Saurio
a5330aa6fb perf/btree: implement fast algorithm for defragment_page 2025-08-05 11:24:14 +03:00
Jussi Saurio
5b84ad6b0f Merge 'Update defragment page to defragment in-place' from João Severo
Change original code from doing a full copy of the original buffer to
modify the buffer in-place using a temporary vector with offsets.

Closes #2258
2025-08-05 11:22:22 +03:00
Jussi Saurio
cd79d2dce5 test/fuzz: add ALTER TABLE column ops to tx isolation fuzz test 2025-08-05 10:05:56 +03:00
Jussi Saurio
685615dc98 test/fuzz/txn: remove assumption about hardcoded column count 2025-08-05 10:04:25 +03:00
Jussi Saurio
c9c5565867 Merge 'Integrate virtual tables with optimizer' from Piotr Rżysko
This PR integrates virtual tables into the query optimizer. It is a
follow-up to https://github.com/tursodatabase/turso/pull/1727.
The most immediate improvement is better support for inner joins
involving TVFs, particularly when TVF arguments are column references.
### Example
The following two queries are semantically equivalent, but require
different join orders to be valid:
```sql
-- TVF depends on `t.id`, so `t` must be evaluated in outer loop
SELECT t.id, series.value
FROM target t, generate_series(t.id, 3) series;

-- Equivalent query, but with reversed table order in the FROM clause
SELECT t.id, series.value
FROM generate_series(t.id, 3) series, target t;
```
Without optimizer integration, the second query would fail because the
planner would attempt to evaluate `generate_series` before `t`. With
this change, the optimizer detects column dependencies and produces the
correct join order in both cases.
### TODO
Support for outer joins with TVFs is still missing and will be addressed
in a follow-up PR.

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

Closes #2439
2025-08-05 09:22:08 +03:00
pedrocarlo
aa8d17cbf1 state machine for ptrmap_get 2025-08-05 01:38:42 -03:00
Piotr Rzysko
59ec2d3949 Replace ConstraintInfo::plan_info with ConstraintInfo::index
The side of the binary expression no longer needs to be stored in
`ConstraintInfo`, since the optimizer now guarantees that it is always
on the right. As a result, only the index of the corresponding constraint
needs to be preserved.
2025-08-05 05:48:29 +02:00
Piotr Rzysko
8fb4fbf8af Make WhereTerm::consumed a plain bool
Now that virtual tables are integrated into the optimizer, this field no
longer needs to be wrapped in Cell<bool>.
2025-08-05 05:48:28 +02:00
Piotr Rzysko
99f87c07c1 Support column references in table-valued function arguments
This change extends table-valued function support by allowing arguments
to be column references, not only literals.

Virtual tables can now reject a plan by returning an error from
best_index (e.g., when a TVF argument references a table that appears
later in the join order). The planner using this information excludes
invalid plans during join order search.
2025-08-05 05:48:28 +02:00
Piotr Rzysko
82491ceb6a Integrate virtual tables with optimizer
This change connects virtual tables with the query optimizer.
The optimizer now considers virtual tables during join order search
and invokes their best_index callbacks to determine feasible access
paths.

Currently, this is not a visible change, since none of the existing
extensions return information indicating that a plan is invalid.
2025-08-05 05:48:28 +02:00
pedrocarlo
0ac040cc87 return IO in some other functions in Pager 2025-08-04 23:28:57 -03:00
pedrocarlo
a4a2425ffd return IO in places where completions are created 2025-08-04 23:28:57 -03:00
Jussi Saurio
a66b56678d Merge 'Reprepare Statements when Schema changes' from Pedro Muniz
Closes #1967
To support this I had to change how we did `epilogue` similarly to how
SQLite does it. SQLIte first declares a `beginWriteOperation` when some
statement is going to necessitate a Write Transaction. And as we now
need to pass the current schema cookie to `epilogue` it was easier to
call epilogue only in one location (like we do with prologue), and just
have each statement declare their intentions separately. This allows us
to not have to pass the Schema around just to do the epilogue. I believe
this is something that @jussisaurio would be interested in.
~Also had to disable the MVCC test, as it was extremely buggy for me.~
Just disabled reprepare statements for MVCC

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

Closes #2214
2025-08-05 00:01:14 +03:00