Commit Graph

3592 Commits

Author SHA1 Message Date
Pere Diaz Bou
578bc9e3e6 extract constant min_header_size 2025-03-30 11:12:11 +02:00
Pere Diaz Bou
8d74f4b8ab remove unnecessary partial ord 2025-03-30 11:07:23 +02:00
Pere Diaz Bou
3899f8ca17 comment header size 2025-03-30 11:03:45 +02:00
Pere Diaz Bou
541b67bd2b rename get_lazy_immutable_record -> get_immutable_record_or_create 2025-03-30 11:00:59 +02:00
Pere Diaz Bou
6ccb2e16d1 safer api for ImmutableRecord recreation 2025-03-30 11:00:13 +02:00
Pere Diaz Bou
f2f6173670 assert capacity didn't change 2025-03-30 10:37:58 +02:00
Pere Diaz Bou
3ac1795c25 fix from_register serialization 2025-03-30 10:31:39 +02:00
Pere Diaz Bou
587cdac2c1 ignore sequential write beause it takes too long 2025-03-29 22:26:29 +01:00
Pere Diaz Bou
37ddf0946f rever testing.db change 2025-03-29 22:09:53 +01:00
Pere Diaz Bou
a13b33fec9 clippy again 2025-03-29 22:07:43 +01:00
Pere Diaz Bou
d9f5cd870d clippy 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
4a9c4cff02 fix comparison of immutable records in seekgt 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
9623cce986 push null refvalue too 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
34c8fd7e6c fix serial_type write 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
1bfec65f23 remove dbg 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
e504262bd5 fix rebase 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
105b421274 make read_record, read_varint and read_value faster
We make read_record faster by not allocating Vec if not needed. This is
why I introduced a simple `SmallVec<T>` that will have a stack allocated
list for the simplest workloads, and a heap allocated if we were to
require more stuff.

Both read_varint and read_value, at least in my mac m4, were not
inlined. Since these functions are called so many times it made sense to
inline them to avoid call overhead. With this I saw something like 20%
improvement over previous commit in my m4.
2025-03-29 22:04:08 +01:00
Pere Diaz Bou
3317195a53 Reusable ImmutableRecord -> allocation reduction
Improve allocation usage from ImmutableRecords by reusing them.
ImmutableRecord is basically a contigous piece of memory that holds the
current record. If we move to some other record we usually deallocate
the previous one and allocate a new one -- obviously this is wasteful.
With this commit we will reuse the ImmutableRecord to allow payload to
be extended if needed or reused if we can, making it faster to iterate
records basically.
2025-03-29 22:04:08 +01:00
Pere Diaz Bou
ee55116ca6 return row as reference to registers 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
5b7fcd27bd make column reuse blob/text fields 2025-03-29 22:02:49 +01:00
Pere Diaz Bou
78e9f1c09a append writer 2025-03-29 22:02:49 +01:00
Pere Diaz Bou
bf37fd3314 wip 2025-03-29 22:02:49 +01:00
Pekka Enberg
4ee60348f2 Merge 'Fixes probably all floating point math issues and floating point display issues.' from Ihor Andrianov
Closes #1206
Closes #447
Closes #1117
Issues:
 1. Rust floating point math fucntions are non deterministic.
 2. SQLite have complex floating point display rules.
I changed rust functions to libm for math ops and implemented Display
trait for OwnedValue:Float. A lot of float formatting SQLite probably
inherits from C have to be handcrafted.

Closes #1208
2025-03-29 17:33:53 +02:00
Ihor Andrianov
09b55a9b41 fix nan to return null 2025-03-29 14:47:08 +02:00
Ihor Andrianov
8b9f34af71 fix tests and return nan as null 2025-03-29 14:46:11 +02:00
Ihor Andrianov
922945e819 all output should go through display 2025-03-29 12:46:06 +02:00
Ihor Andrianov
6e04709c4f add comprehensive float display trait 2025-03-29 12:44:34 +02:00
Ihor Andrianov
303f1b3749 replace std math functions with libm for compat 2025-03-29 12:16:14 +02:00
Pere Diaz Bou
28904e74ae Merge 'Make BTreeCell/read_payload not allocate any data + overflow fixes' from Pere Diaz Bou
This PR has two parts:
## 1. Make reading cells faster
My benchmark was simple, running `test_sequential_write` test and see
how long it takes. It is a nice benchmark because it will write a new
row and then `select * from t` for every write to check the contents.
## From:
```bash
cargo test test_sequential_write --release -- --nocapture --test-threads=1   7.21s user 0.34s system 88% cpu 8.527 total
```
### To:
```bash
cargo test test_sequential_write --release -- --nocapture --test-threads=1  3.14s user 0.31s system 82% cpu 4.161 total
```
## 2. Fix reading overflow pages.
The code to read overflow pages was wrong, `read_payload` would try to
read as many overflow pages as possible but if there weren't in cache
they would return `IO` and not read more pages after that. This PR makes
every read record to check if it needs to read from overflow pages and
if not, it will simply read from the current page.

Closes #1141
2025-03-28 12:25:34 +01:00
Pere Diaz Bou
cb85ba8e82 fix extensions.py test 2025-03-28 11:58:03 +01:00
Pekka Enberg
704b4d3baf Merge 'JavaScript binding improvements' from Pekka Enberg
Closes #1204
2025-03-28 12:39:43 +02:00
Pere Diaz Bou
c5b718ac32 fix review comments 2025-03-28 11:30:19 +01:00
Pere Diaz Bou
01cdcf719c remove ignored from sequential tests 2025-03-28 11:30:19 +01:00
Pere Diaz Bou
83d0c9a1b6 fix read overflow page procedure 2025-03-28 11:30:19 +01:00
Pere Diaz Bou
f51c20adf0 read overflow pages on demand 2025-03-28 11:12:43 +01:00
Pere Diaz Bou
dc8acf1a4a cell_get no allocations 2025-03-28 11:12:27 +01:00
Pekka Enberg
94262e4660 bindings/javascript: Fix Statement.get() implementation 2025-03-28 11:32:55 +02:00
Pekka Enberg
7348eb0aa1 bindings/javascript: Add better-sqlite3 tests 2025-03-28 11:32:55 +02:00
Pekka Enberg
11d1dcf31a bindings/javascript: Run tests in parallel 2025-03-28 10:38:40 +02:00
Pekka Enberg
387b68fc06 Merge 'Expose 'Explain' to prepared statement to allow for alternate Writer ' from Preston Thorpe
### The problem:
I often need to copy the output of an `Explain` statement to my
clipboard. Currently this is not possible because it currently will only
write to stdout.
All other limbo output, I am able to run `.output file` in the CLI, then
enter my query and in another tmux pane I simply `cat file | xclip -in
-selection clipboard`.
### The solution:
Expose a `statement.explain()` method that returns the query explanation
as a string. If the user uses something like `execute` instead of
prepare, it will default to `stdout` as expected, but this allows the
user to access the query plan on the prepared statement and do with it
what they please.

Closes #1166
2025-03-28 09:55:58 +02:00
Pekka Enberg
8caa234df3 simulator: Reduce info-level logging
Make the simulator less noisy for casual runs.
2025-03-28 08:10:57 +02:00
Pekka Enberg
9a646acead Merge 'Add BTree balancing after delete' from Krishna Vishal
This PR adds balancing after delete.
- [x] Remove linear search for cell in the page
- [x] Change the implementation to state machine approach
- [x] Handle cases when balancing is needed and not needed
- [x] Add unit test to verify that balancing after delete maintains
BTree integrity.
Fixes: https://github.com/tursodatabase/limbo/issues/1019
Closes: https://github.com/tursodatabase/limbo/issues/455

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

Closes #1147
2025-03-28 07:32:15 +02:00
Pekka Enberg
8d682fe857 Merge 'Kill test environment' from Pekka Enberg
...not sure why we added it in the first place, but it spams PRs all the
time.

Closes #1196
2025-03-28 07:31:59 +02:00
Pekka Enberg
41bdf25433 Merge 'Remove public unlock method from SpinLock to prevent unsafe aliasing' from Krishna Vishal
Currently we can create two guards and unlock one of them and still have
two mutable references to the same data.
By being able to unlock only via guard we prevent unsafe scenarios.
Currently, the test below will pass and shows that we can hold two
mutable references to the same data. After this fix, this would result
in a deadlock (have to remove `lock.unlock()`)
```rust
#[test]
fn two_mutable_reference() {
    let lock = SpinLock::new(42);
    let guard = lock.lock();
    lock.unlock();
    let guard2 = lock.lock();

    // two mutable references to same data
    *guard = 10;
    *guard2 = 20;

    assert_eq!(*guard, 20);
    assert_eq!(*guard2, 20);
}
```
Note: The javascript action failure is unrelated to this PR.

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

Closes #1194
2025-03-27 20:43:16 +02:00
Pekka Enberg
4ccfdb1639 Kill test environment
...not sure why we added it in the first place, but it spams PRs all the
time.
2025-03-27 19:46:30 +02:00
Pekka Enberg
c71dad7683 Merge 'Introduce Register struct ' from Pere Diaz Bou
OwnedValue has become a powerhouse of madness, mainly because I decided
to do it like that when I first introduced AggContext. I decided it was
enough and I introduced a `Register` struct that contains `OwnedValue`,
`Record` and `Aggregation`, this way we don't use `OwnedValue` for
everything make everyone's life harder.
This is the next step towards making ImmutableRecords the default
because I want to remove unnecessary allocations. Right now we clone
OwnedValues when we generate a record more than needed.

Closes #1188
2025-03-27 19:45:11 +02:00
Pere Diaz Bou
d01423df83 fix clippy 2025-03-27 17:54:32 +01:00
Pere Diaz Bou
9291f60722 Introduce Register struct
OwnedValue has become a powerhouse of madness, mainly because I decided
to do it like that when I first introduced AggContext. I decided it was
enough and I introduced a `Register` struct that contains `OwnedValue`,
`Record` and `Aggregation`, this way we don't use `OwnedValue` for
everything make everyone's life harder.

This is the next step towards making ImmutableRecords the default
because I want to remove unnecessary allocations. Right now we clone
OwnedValues when we generate a record more than needed.
2025-03-27 17:53:02 +01:00
krishvishal
dcd92954f4 Remove unlock method and move it to guard's drop.
This makes the interface safe and prevents unlocking while still holding the guard
2025-03-27 18:45:05 +05:30
Pekka Enberg
af6e9cd2c2 Merge 'Handle limit zero case in query plan emitter' from Preston Thorpe
closes #1190
Don't emit full query plan and open table if 0 `LIMIT`
```console
limbo> explain select * from t limit 0;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     2     0                    0   Start at 2
1     Halt               0     0     0                    0
2     Transaction        0     0     0                    0   write=false
3     Goto               0     1     0                    0
```
Surprisingly, sqlite will still emit the Open/Rewind/Column/etc, etc for
this case. Definitely feels super unnecessary.

Closes #1191
2025-03-27 08:59:54 +02:00