Commit Graph

2034 Commits

Author SHA1 Message Date
PThorpe92
f6a64a7b15 Support OFFSET clause for LIMIT in UPDATE queries 2025-04-04 12:35:30 -04:00
Pekka Enberg
c3eaf47180 Merge 'Add support for default values in INSERT statements' from Diego Reis
While working on #494 I noticed that default values defined in schemas
weren't being applied.
Before:
![image](https://github.com/user-attachments/assets/af3a31be-
accd-47b4-848f-3820497e32ac)
Now:
![image](https://github.com/user-
attachments/assets/0ccb194c-4caa-481d-8f47-2405c3db06bb)

Closes #1249
2025-04-04 08:59:44 +03:00
Diego Reis
43daba9942 core/translate: Add support for default values in INSERT statements 2025-04-04 01:32:13 -03:00
Diego Reis
38d842d675 docs/insn: Standardizes comments for insn to doc comments 2025-04-04 00:56:54 -03:00
PThorpe92
ae2be30204 Move init label to proper place in create vtab translation 2025-04-03 20:22:14 -04:00
TcMits
56fa9049c3 fix: overflow pos in write_page 2025-04-03 15:02:53 +07:00
Pekka Enberg
24063bd9c0 core/vdbe: Add newline between op functions 2025-04-02 18:57:07 +03:00
Pekka Enberg
c592e27dca core/vdbe: Move explain() to last method in Program
...it's the least interesting one and we should have `step()` at the top.
2025-04-02 18:55:35 +03:00
Pekka Enberg
ed1854c8de Merge 'Request load page on insert_into_page' from Pere Diaz Bou
We assumed page was loaded because before inserting we would move there.
`NewRowId` unfortunately moves cursor to the rightmost page causing
eviction of root page -- this arose the issue with `insert_into_page`
not loading the page we were supposed to have loaded so I added
`return_if_locked_maybe_load` which is a utility macro to check if the
page is locked and if not, load it if needed.

Closes #1138
2025-04-02 18:52:25 +03:00
Pere Diaz Bou
65c4cb1e0e Merge 'core/vdbe: Rename execute_insn_* to op_*' from Pekka Enberg
The "execute::execute_insn" prefix is noisy, let's rename the
instruction operation functions to something shorter and sweeter.

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

Closes #1235
2025-04-02 17:25:12 +02:00
Pekka Enberg
265457f175 Merge 'Don't emit Transaction for simple SELECT statements' from Diego Reis
First step to close #1226.
Before:
![image](https://github.com/user-
attachments/assets/990bc6e2-a8f1-44db-9f82-f70a430663c1)
After:
![image](https://github.com/user-
attachments/assets/a587e207-d10f-487b-97b1-47b46f5dceff)
Reusing the same register is a bit trickier, I'm understanding how
SQLite does this optimization to apply here as well.
EDIT: Now we reuse the register and have the same number of bytecodes as
SQLite.
![image](https://github.com/user-
attachments/assets/bd7d769b-a680-4e77-ac2d-a3f1728bfdb7)

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

Closes #1227
2025-04-02 18:12:20 +03:00
Pekka Enberg
3420955db7 core/vdbe: Rename execute_insn_* to op_*
The "execute::execute_insn" prefix is noisy, let's rename the
instruction operation functions to something shorter and sweeter.
2025-04-02 18:02:02 +03:00
Pere Diaz Bou
5dedc68fda remove arc import 2025-04-02 16:56:34 +02:00
Pere Diaz Bou
e85fb86ff4 Request load page on insert_into_page
We assumed page was loaded because before inserting we would move there. `NewRowId` unfortunately moves cursor to the rightmost page causing eviction of root page -- this arose the issue with `insert_into_page` not loading the page we were supposed to have loaded so I added `return_if_locked_maybe_load` which is a utility macro to check if the page is locked and if not, load it if needed.
2025-04-02 16:24:53 +02:00
Pere Diaz Bou
46814d2bd7 ignore warning mut_from_ref 2025-04-02 16:18:36 +02:00
Pere Diaz Bou
e2d00a9f96 inline start transactions from pager and wal
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [30.543 ns 30.585 ns 30.632 ns]
2025-04-02 16:18:36 +02:00
Pere Diaz Bou
2a49fe9bd2 Remove RWLock from Shared wal state
WalShared state can be shared without having to wrap everything with a
lock, and instead use atomics on some places and rwlock on others -- for
now.

## Results:
From:
----
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [34.125 ns 34.218 ns 34.324 ns]
Execute `SELECT 1`/sqlite_execute_select_1
                        time:   [28.124 ns 28.254 ns 28.385 ns]

To:
----
Gnuplot not found, using plotters backend
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [31.919 ns 32.113 ns 32.327 ns]
Execute `SELECT 1`/sqlite_execute_select_1
                        time:   [29.662 ns 29.900 ns 30.139 ns]
2025-04-02 16:18:36 +02:00
Pekka Enberg
cd5ef7c7db Merge 'Reuse register in binary expressions if they're equal ' from Diego Reis
Alongside with #1227, this PR closes #1226
Before:
![image](https://github.com/user-attachments/assets/d9fd4ff4-957d-46cd-
abe0-63d0b2c4acdb)
After:
![image](https://github.com/user-
attachments/assets/2ce4b8f1-f8f8-423a-8d35-d947de2794cb)

Closes #1234
2025-04-02 17:02:35 +03:00
Pere Diaz Bou
66f70d571d fmt 2025-04-02 13:14:26 +00:00
Pere Diaz Bou
f5221589f0 remove wrong usage of feature = json 2025-04-02 15:00:51 +02:00
Pere Diaz Bou
7e4b57f2e2 VDBE with direct function dispatch
This PR is unapologetically stolen from @vmg's implementation in Vitess
implemented here https://github.com/vitessio/vitess/pull/12369. If you
want a more in depth explanation of how this works you can read the
[blog post he carefully
wrote](https://planetscale.com/blog/faster-interpreters-in-go-catching-up-with-cpp).

In limbo we have a huge problem with [register
spilling](https://en.wikipedia.org/wiki/Register_allocation), this can
be easily observed with the prolog of `Program::step` before:
```llvm
start:
    %e.i.i304.i = alloca [0 x i8], align 8
    %formatter.i305.i = alloca [64 x i8], align 8
    %buf.i306.i = alloca [24 x i8], align 8
    %formatter.i259.i = alloca [64 x i8], align 8
    ..................... these are repeated for hundreds of lines
.....................
    %formatter.i52.i = alloca [64 x i8], align 8
    %buf.i53.i = alloca [24 x i8], align 8
    %formatter.i.i = alloca [64 x i8], align 8
    %buf.i.i = alloca [24 x i8], align 8
    %_87.i = alloca [48 x i8], align 8
    %_82.i = alloca [24 x i8], align 8
    %_73.i = alloca [24 x i8], align 8
    %_66.i8446 = alloca [24 x i8], align 8
    %_57.i = alloca [24 x i8], align 8
    %_48.i = alloca [24 x i8], align 8
```

After these changes we completely remove the need of register spilling
(yes that is the complete prolog):
```llvm
start:
    %self1 = alloca [80 x i8], align 8
    %pager = alloca [8 x i8], align 8
    %mv_store = alloca [8 x i8], align 8
    store ptr %0, ptr %mv_store, align 8
    store ptr %1, ptr %pager, align 8
    %2 = getelementptr inbounds i8, ptr %state, i64 580
    %3 = getelementptr inbounds i8, ptr %state, i64 576
    %4 = getelementptr inbounds i8, ptr %self, i64 16
    %5 = getelementptr inbounds i8, ptr %self, i64 8
    %6 = getelementptr inbounds i8, ptr %self1, i64 8
    br label %bb1, !dbg !286780
```
When it comes to branch prediction, we don't really fix a lot because
thankfully rust already compiles `match` expressions
to a jump table:

```llvm
%insn = getelementptr inbounds [0 x %"vdbe::insn::Insn"], ptr %self657,
i64 0, i64 %index, !dbg !249527
%332 = load i8, ptr %insn, align 8, !dbg !249528, !range !38291,
!noundef !14
switch i8 %332, label %default.unreachable26674 [
    i8 0, label %bb111
    i8 1, label %bb101
    i8 2, label %bb100
    i8 3, label %bb110
    ...
    i8 104, label %bb5
    i8 105, label %bb16
    i8 106, label %bb14
], !dbg !249530
```

Some results
----
```
function dispatch:
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [29.498 ns 29.548 ns 29.601 ns]
                        change: [-3.6125% -3.3592% -3.0804%] (p = 0.00 <
0.05)

main:
Execute `SELECT 1`/limbo_execute_select_1
                        time:   [33.789 ns 33.832 ns 33.878 ns]
```
2025-04-02 14:55:37 +02:00
Diego Reis
3c531ac5ec core/expr: Reuse register in binary expressions if they're equal 2025-04-02 09:15:41 -03:00
Diego Reis
86f8719b69 core/expr: Extract binary insn emission in a separate function 2025-04-02 09:14:01 -03:00
Diego Reis
fe37046536 core/emitter: Don't emit for statements that doesn't reference any tables 2025-04-02 08:59:52 -03:00
Diego Reis
6660a99003 core/emitter: Refactor the epilogue function to receive an enum 2025-04-02 08:56:19 -03:00
Pekka Enberg
7394ad6854 Disable more b-tree fuzzers... 2025-04-02 13:38:09 +03:00
Pekka Enberg
cc8340d30e Disable btree_insert_fuzz_run_random test 2025-04-02 09:15:01 +03:00
Pekka Enberg
6199c3994a Merge 'Create plan for Update queries' from Preston Thorpe
closes #1186, or at least works towards it by implementing an actual
Plan for update queries instead of translating everything inline. This
allows for actually using index's, rewriting const expressions, pushing
predicates instead of hardcoding a full scan in the translation.
### TODOs:
1.  `RETURNING` clause/result columns
2.  `OFFSET` clauses
3. on conflict
### LIMIT:
By supporting `LIMIT` directly in update queries, we'll have to put the
tests outside of the compatibility tests, maybe in the CLI tests.

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

Closes #1189
2025-04-01 17:33:32 +03:00
Pere Diaz Bou
6b05dbddb0 remove unnecessary code while building count old and size old balancing 2025-04-01 13:11:55 +02:00
Pere Diaz Bou
141303e330 Validate cells inside a page after each operation
We need to ensure an operation doesn't transform the cells inside a page
to an invalid state. In debug mode we can enable a
`debug_validate_cells` with `#[cfg(debug_assertions)]` so that it is
skipped on release mode.

Modify pager logs
2025-04-01 11:19:23 +02:00
Pere Diaz Bou
bab748e538 fix key generation 2025-04-01 01:05:07 +02:00
Pere Diaz Bou
d2642dfe0c skip repeated keys 2025-04-01 00:58:10 +02:00
Pere Diaz Bou
4308f8c73a Fix propagation of divider cell balancing interior page
Newly added divider cells to parent of an interior page must point to
the page in question. Moreover rightmost pointer of the page will point
to previous divider cell pointer.
2025-04-01 00:58:10 +02:00
Pere Diaz Bou
24e4af7ee8 Allow balance_root to balance with interior pages 2025-03-31 12:42:01 +02:00
Pere Diaz Bou
78f6480e8f remove ignored from fuzz tests 2025-03-31 10:59:28 +02:00
Pere Diaz Bou
bc660446a8 fuzz test ensure we "seek" until done 2025-03-31 10:57:55 +02:00
Pere Diaz Bou
0653ccf711 ensure btree fuzz doesn't repeat keys for now 2025-03-31 10:57:30 +02:00
Pekka Enberg
4c93c69e5a Merge 'Let remainder (%) accept textual arguments' from Anton Harniakou
Also I added more tests for exec_add, exec_subtract, exec_multiply,
exec_divide, exec_remainder.

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

Closes #1214
2025-03-31 10:40:21 +03:00
Pekka Enberg
77e9737b92 Merge 'JSON code cleanups' from Pekka Enberg
Just some renames to avoid redundant "json_" prefix and minor
conditional compilation cleanups.

Closes #1216
2025-03-31 10:40:09 +03:00
Pekka Enberg
169864456e Merge 'Fix IdxCmp insn comparisons' from Jussi Saurio
We never hit bugs due to these because of 1. not having multi column
indexes in our TCL test databases, 2. otherwise not really having Rust
tests involving indexes, and 3. `IdxLt` and `IdxLe` not actually being
used anywhere yet
Also as @PThorpe92 pointed out there are some nuances to the comparison
logic we may need to eventually implement regarding comparisons with
uneven number of keys:
https://github.com/sqlite/sqlite/blob/master/src/vdbeaux.c#L4719

Reviewed-by: Preston Thorpe (@PThorpe92)

Closes #1215
2025-03-31 10:40:01 +03:00
Pekka Enberg
5a60815484 core/json: Remove redundant conditional compilation
The top-level `json` module declaration is already conditional on "json"
feature so no need to do it here.
2025-03-31 09:40:01 +03:00
Pekka Enberg
6258dda5f1 core/json: Rename json_path.rs to path.rs 2025-03-31 09:40:01 +03:00
Pekka Enberg
4a91988755 core/json: Rename json_operations.rs to ops.rs 2025-03-31 09:33:30 +03:00
Pekka Enberg
4b77f52bac core/json: Rename json_cache.rs to cache.rs 2025-03-31 09:32:34 +03:00
Jussi Saurio
42e25d23dd Fix IdxCmp insn comparisons 2025-03-30 23:01:41 +03:00
PThorpe92
211c9a0212 Remove From impl on iteration direction for sort order 2025-03-30 12:18:12 -04:00
PThorpe92
516e443a2b Fix use index cursor id in emitter and prevent reinsert pk on update 2025-03-30 12:15:25 -04:00
PThorpe92
ff02d74afb Fix update queries when limit is 0 2025-03-30 12:15:25 -04:00
PThorpe92
a88ce2a4b7 Correct comment on update plan 2025-03-30 12:15:25 -04:00
PThorpe92
3f4636196c Fix error message for non btree table 2025-03-30 12:15:25 -04:00