Commit Graph

961 Commits

Author SHA1 Message Date
PThorpe92
a13fc3515e Fix cargo fmt warning 2025-07-22 21:47:15 -04:00
Glauber Costa
a10d8d7f94 silence clippy errors with features disabled
When compiling with features disabled, there are lots of clippy
warnings. This PR silences them.

For the utils file, I am using a bit of a hammer and just allowing
unused stuff in the whole file. Due to the box of utilities nature of
this file, it'll always be the case that things will be unused depending
on the feature-set.
2025-07-22 20:37:45 -05:00
PThorpe92
9c785ea0ea Merge 'make readonly a property of the database' from Glauber Costa
There's no such thing as a read-only connection.
In a normal connection, you can have many attached databases. Some r/o,
some r/w.
To properly fix that, we also need to fix the OpenWrite opcode. Right
now we are passing a name, which is the name of the table. That
parameter is not used anywhere. That is also not what the SQLite opcode
specifies. Same as OpenRead, the p3 register should be the database
index.
With that change, we can - for now - pass the index 0, which is all we
support anyway, and then use that to test if we are r/o.

Reviewed-by: Preston Thorpe (@PThorpe92)

Closes #2232
2025-07-22 21:12:08 -04:00
Levy A.
203239ff30 refactor: safer db_state 2025-07-22 17:20:29 -03:00
Glauber Costa
57a1113460 make readonly a property of the database
There's no such thing as a read-only connection.
In a normal connection, you can have many attached databases. Some
r/o, some r/w.

To properly fix that, we also need to fix the OpenWrite opcode. Right
now we are passing a name, which is the name of the table. That
parameter is not used anywhere. That is also not what the SQLite opcode
specifies. Same as OpenRead, the p3 register should be the database
index.

With that change, we can - for now - pass the index 0, which is all
we support anyway, and then use that to test if we are r/o.
2025-07-22 09:41:32 -05:00
PThorpe92
f7ba8efdbd Switch back to std::mutex because it was an unnecessary change 2025-07-21 19:20:17 -04:00
PThorpe92
411c4f059a Load compile time extensions on the initial db startup instead of once per conn 2025-07-21 19:09:31 -04:00
Jussi Saurio
9936748132 Merge 'Avoid redundant decoding of record headers when reading sorted chunk files' from Iaroslav Zeigerman
Currently, each record header is decoded at least twice: once to
determine the record size within the read buffer (in order to construct
the `ImmutableRecord` instance), and again later when decoding the
record for comparison. This redundant decoding can have a noticeable
negative impact on performance when records are wide (eg. contain
multiple columns).
This update modifies the (de)serialization format for sorted chunk files
by prepending a record size varint to each record payload. As a result,
only a single varint needs to be decoded to determine the record size,
eliminating the need to decode the full record header during reads.

Closes #2176
2025-07-20 23:54:54 +03:00
Glauber Costa
65312baee6 fix opcodes missing a database register
Two of the opcodes we implement (OpenRead and Transaction) should have
an opcode specifying the database to use, but they don't.

Add it, and for now always use 0 (the main database).
2025-07-20 12:27:26 -05:00
Glauber Costa
6506b3147d implement pragma application_id
Just for completeness, because it is easy.
2025-07-19 20:44:06 -05:00
Iaroslav Zeigerman
10a848fbc5 address nit 2025-07-19 18:40:43 +02:00
Iaroslav Zeigerman
5d47502e3a Avoid redundant decoding of record headers when reading sorted chunk files 2025-07-19 06:08:27 +02:00
Jussi Saurio
4d15725b6f sorter: fix sorter panic on SortedChunkIOState::WaitingForRead
The following sequence of events is possible:

- init_chunk_heap() called
- chunk A status is WriteComplete, so chunk.read() gets called on chunk A
- some other chunk B is in WaitingForWrite status after flush()
- init_chunk_heap() returns IOResult::IO
- init_chunk_heap() is called again
- we panic because chunk A is in WaitingForRead status

So - we just allow WaitingForRead status in init_chunk_heap() instead.

This panic was caught thanks to Pedro's IO latency enhancement to the sim!
2025-07-18 14:18:51 +03:00
Jussi Saurio
55151a8061 Fix cases where Insn::Insert needs to seek to ensure correct insertion 2025-07-18 13:48:23 +03:00
Jussi Saurio
9ee6988fc5 VDBE: NewRowid needs to call next() in case op_not_exists() is not called afterwards 2025-07-18 13:48:23 +03:00
Jussi Saurio
4f0ef663e2 btree: add target cell tracking for EQ seeks 2025-07-18 13:48:23 +03:00
Pekka Enberg
02f4bc39b3 Merge 'Reanimate MVCC' from Pekka Enberg
Bit-rot happened. Bring MVCC back from the dead.

Closes #2136
2025-07-18 11:22:49 +03:00
Jussi Saurio
bbd7f32d80 Merge 'Fix rollback for TxErrors' from Diego Reis
Fixes #2153.
Not so sure if SQLite doesn't rollback in more cases, we should
definitively check this out.

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

Closes #2154
2025-07-18 10:49:29 +03:00
Iaroslav Zeigerman
28ff170e14 improve sorter settings in the fuzz test 2025-07-18 07:41:15 +02:00
Iaroslav Zeigerman
76e748146b rebase 2025-07-18 07:30:08 +02:00
Iaroslav Zeigerman
f6f1d076da verify that records remain unchanged after sorting 2025-07-18 07:28:37 +02:00
Iaroslav Zeigerman
d9751212d7 make a fuzz sorter test 2025-07-18 07:28:37 +02:00
Iaroslav Zeigerman
20bdbd5ca5 address suggestions 2025-07-18 07:28:37 +02:00
Iaroslav Zeigerman
edf2be1432 fix conflicts 2025-07-18 07:28:37 +02:00
Iaroslav Zeigerman
6a609398fe cosmetic fix 2025-07-18 07:28:37 +02:00
Iaroslav Zeigerman
a88b828268 Fix clippy 2025-07-18 07:28:36 +02:00
Iaroslav Zeigerman
fd042ac4c8 Use IOResult insteaed of CursorResult 2025-07-18 07:28:36 +02:00
Iaroslav Zeigerman
78f3bf3475 Core: Introduce external sorting 2025-07-18 07:28:36 +02:00
Diego Reis
9ade79b3ad Do not rollback in TxError
Fixes #2153. Not so sure if SQLite doesn't rollback in more cases, we
should definitively check this out.
2025-07-18 01:11:51 -03:00
Jussi Saurio
483dc27539 Merge 'make most instrumentation levels to be Debug or Trace instead' from Pedro Muniz
Span creation in debug mode is very slow and impacts our ability to run
the Simulator faster.

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

Closes #2146
2025-07-17 23:45:07 +03:00
Jussi Saurio
1b52b5c764 Merge 'chore: update rust to version 1.88.0' from Nils Koch
This PR updates to version Rust 1.88.0 ([Release
notes](https://releases.rs/docs/1.88.0/)) and fixes all the clippy
errors that come with the new Rust version.
This is possible in the latest Rust version:
```rust
if let Some(foo) = bar && foo.is_cool() {
  ...
}
```
There are three complications in the migration (so far):
- A BUNCH of Clippy warnings (mostly fixed in
https://github.com/tursodatabase/limbo/pull/1827)
- Windows cross compilation failed; linking `advapi32` on windows fixes
it
  - Since Rust 1.87.0, advapi32 is not linked by default anymore
([Release notes](https://github.com/rust-
lang/rust/blob/master/RELEASES.md#compatibility-notes-1),
[PR](https://github.com/rust-lang/rust/pull/138233))
- Rust is more strict with FFIs and aligning pointers now. CI checks
failed with error below
  - Fixed in https://github.com/tursodatabase/turso/pull/2064
```
thread 'main' panicked at
core/ext/vtab_xconnect.rs:64:25:
misaligned pointer dereference: address must be
a multiple of 0x8 but is 0x7ffd9d901554
```

Closes #1807
2025-07-17 23:35:33 +03:00
pedrocarlo
c15f1e02d3 make most instrumentation levels to be Debug or Trace instead. Span creation in debug mode is very slow and impacts our ability to run the Simulator fast enough 2025-07-17 16:48:24 -03:00
Pekka Enberg
2b1ee907a9 core/vdbe: Fix op_new_rowid() with MVCC 2025-07-17 14:13:22 +03:00
Pekka Enberg
8e338d3e7a core/vdbe: Fix SetCookie when MVCC is enabled 2025-07-17 14:13:22 +03:00
Pekka Enberg
1fc6126157 core/storage: Allocate page1 lazily for MVCC transactions 2025-07-17 14:13:22 +03:00
Jussi Saurio
5a2efa3077 Merge 'refactor/btree&vdbe: fold index key info (sort order, collations) into a single struct' from Jussi Saurio
These are nearly always used together in some form, so it makes sense to
colocate them, and it also makes many code paths simpler, as we don't
separately pass `collations` and `key_sort_order` around
As a side effect, as the bitfield-based `IndexKeySortOrder` is removed,
we now remove the arbitrary 64 column restriction for indexes, see e.g.
this sim failure which fails to 64+ index columns (not sure why it uses
an index if they are disabled):
https://github.com/tursodatabase/turso/actions/runs/16339391964/job/4615
8045158

Closes #2131
2025-07-17 11:55:56 +03:00
Jussi Saurio
e8199cb26c btree/vdbe: fold index key info (sort order, collations) into a single struct
These are nearly always used together in some form, so it makes sense to colocate
them, and it also makes many code paths simpler.
2025-07-17 10:58:43 +03:00
Nils Koch
8dc066503e chore: fix clippy errors 2025-07-16 19:34:42 +01:00
Levy A.
8e8f1682df add with_schema_mut
removes all repeated `Arc::make_mut`
2025-07-16 13:54:39 -03:00
Levy A.
4c77d771ff only copy schema on writes 2025-07-16 13:54:36 -03:00
Diego Reis
817ad8d50f Separate user-callable cacheflush from internal cacheflush logic
Cacheflush should only spill pages to WAL as non-commit frames, without checkpointing nor syncing. Check SQLite's sqlite3PagerFlush
2025-07-16 11:08:50 -03:00
Nikita Sivukhin
41482915f6 make unixepoch to return i64 2025-07-16 14:02:56 +04:00
Jussi Saurio
f482424d77 Merge 'small refactor: rename "amount" to "extra_amount"' from Nikita Sivukhin
Small refactoring to reduce confusion (I was caught in this trap and set
`amount` to one in CDC branch during development)
Also, this PR slightly fix broken `concat_ws` emit logic.

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

Closes #2100
2025-07-16 06:51:35 +03:00
Diego Reis
0e9771ac07 refactor: Change redundant "Status" enums to IOResult
Let's unify the semantics of "something done" or yields I/O into a
single type
2025-07-15 20:56:18 -03:00
Diego Reis
d0af54ae77 refactor: Change CursorResult to IOResult
The reasoning here is to treat I/O operations (Either is "Done" or
yields to IO) with the same generic type.
2025-07-15 20:52:25 -03:00
Nikita Sivukhin
be0a607ba8 rename amount -> extra_amount 2025-07-16 00:46:17 +04:00
Jussi Saurio
927a1f158a Merge 'btree: unify table&index seek page boundary handling' from Jussi Saurio
## Background
PR #2065 fixed a bug with table btree seeks concerning boundaries of
leaf pages.
The issue was that if we were e.g. looking for the first key greater
than (GT) 100, we always assumed the key would either be found on the
left child page of a given divider (e.g. divider 102) or not at all,
which is incorrect. #2065 has more discussion and documentation about
this, so read that one for more context.
## This PR
We already had similar handling for index btrees as #2065 introduced for
table btrees, but it was baked into the `BTreeCursor` struct's seek
handling itself, whereas #2065 handled this on the VDBE side.
This PR unifies this handling for both table and index btrees by always
doing the additional cursor advancement in the VDBE.
Unfortunately, unlike table btrees, index btrees may also need to do an
additional advance when they are looking for an exact match. This
resulted in a bigger refactor than anticipated, since there are quite a
few VDBE instructions that may perform a seek, e.g.: `IdxInsert`,
`IdxDelete`, `Found`, `NotFound`, `NoConflict`. All of these can
potentially end up in a similar situation where the cursor needs one
more advance after the initial seek, and they were currently calling
`cursor.seek()` directly and expecting the `BTreeCursor` to handle the
auto-advance fallback internally.
For this reason, I have 1. removed the "TryAdvance"-ish logic from the
index btree internals and 2. extracted a common VDBE helper `fn
seek_internal()` - heavily based on the existing `op_seek_internal()`,
but decoupled from instructions and the program counter - which all the
interested VDBE instructions will call to delegate their seek logic.
Closes #2083

Reviewed-by: Nikita Sivukhin (@sivukhin)
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #2084
2025-07-15 18:02:52 +03:00
meteorgan
cf126824de Support set page size 2025-07-15 16:34:07 +08:00
Jussi Saurio
553396e9ca btree: unify table&index seek page boundary handling
PR #2065 fixed a bug with table btree seeks concerning boundaries
of leaf pages.

The issue was that if we were e.g. looking for the first key greater than
(GT) 100, we always assumed the key would either be found on the left child
page of a given divider (e.g. divider 102), which is incorrect. #2065 has more
discussion and documentation about this, so read that one for more context.

Anyway:

We already had similar handling for index btrees, but it was baked into
the `BTreeCursor` struct's seek handling itself, whereas #2065 handled this
on the VDBE side.

This PR unifies this handling for both table and index btrees by always doing
the additional cursor advancement in the VDBE.

Unfortunately, since indexes may also need to do an additional advance when they
are looking for an exact match, this resulted in a bigger refactor than anticipated,
since there are quite a few VDBE instructions that may perform a seek, e.g.:
`IdxInsert`, `IdxDelete`, `Found`, `NotFound`, `NoConflict`.

All of these can potentially end up in a similar situation where the cursor needs
one more advance after the initial seek.

For this reason, I have extracted a common VDBE helper `fn seek_internal()` which
all the interested VDBE instructions will call to delegate their seek logic.
2025-07-14 16:46:43 +03:00
Pekka Enberg
1653b0883a Merge 'core/vector: Euclidean distance support for vector search' from KarinaMilet
This PR provides Euclidean distance support for limbo's vector search.
At the same time, some type abstractions are introduced, such as
`DistanceCalculator`, etc. This is because I hope to unify the current
vector module in the future to make it more structured, clearer, and
more extensible.
While practicing Euclidean distance for Limbo, I discovered that many
checks could be done using the type system or in advance, rather than
waiting until the distance is calculated. By building these checks into
the type system or doing them ahead of time, this would allow us to
explore more efficient computations, such as automatic vectorization or
SIMD acceleration, which is future work.

Reviewed-by: Nikita Sivukhin (@sivukhin)

Closes #1986
2025-07-14 13:07:20 +03:00