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
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
First step to close#1226.
Before:

After:

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.

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Closes#1227
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.
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]
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
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
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.
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
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