Fix codegen for `CAST` expression and also adjust implementation of
`CAST: Real -> Int` because `SQLite` use "closest integer between the
REAL value and zero" as a CAST result.
Closes#956
Add `COALESCE` function in fuzz test and fix bug (found by fuzzer with
`COALESCE`) related to the resolution of labels which needs to be
resolved to next emitted instruction.
Before, code assumed that no two labels will need to be resolved to next
emitted instruction. But this assumption is wrong (at least in current
codegen logic) for example for following expression `COALESCE(0,
COALESCE(0, 0))`. Here, both `COALESCE` functions will create label and
resolve it to next emitted instruction in the end of generation. So, in
this case one of the labels will be actually "orphaned" and never be
assigned any position in the emitted code.
Closes#955
(after fixing complicated b-tree bugs - I want to end my day with the
joy of fixing simple bugs)
This PR fix bug in emit (which was introduced after switch from
`HashMap` to `Vec`) and also align `CASE` codegen in case of `NULL`
result from `WHEN` clause with SQLite behaviour.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#953
This PR introduce simple fuzz test for BTree insertion algorithm and
fixes few bugs found by fuzzer
- BTree algorithm returned early although there were overflow pages on
stack and more rebalances were needed
- BTree balancing algorithm worked under assumption that single page
will be enough for rebalance - although this is not always true (if page
were tightly packed with relatively big cells, insertion of new very big
cell can require 3 split pages to distribute the content between them)
- `overflow_cells` wasn't cleared properly during rebalancing
- insertions of dividers to the parent node were implemented incorrectly
- `defragment_page` didn't reset
`PAGE_HEADER_OFFSET_FRAGMENTED_BYTES_COUNT` field which can lead to
suboptimal usage of pages
Closes#951
We expose Wal trait as public, but there are three types in its
signature that are private.
Notice I chose to expose limbo_core::result instead of
limbo_core::result::LimboResult, since LimboResult is the only type in
that module.
Closes#939
- right-nested expression can generate multiple labels which needs to be
resolved to next generated instruction
- for example, COALESCE(0, COALESCE(0, 1))
the boxings will continue until morale improves
<img width="621" alt="Screenshot 2025-02-09 at 14 16 21"
src="https://github.com/user-
attachments/assets/887d218d-3db7-4a64-ad81-b7431adb23bb" />
Closes#947
- if we have page which is tightly packed with relatively big cells, we
will be unable to balance its content if we will insert very big
(~page size) cell in the middle (because nothing can't be merged with
new cell - so we will need to split 1 page into 3)
This makes io_uring the default in CLI, but makes it non-default in
core. Before, if one built CLI without io_uring, core still built with
it as it was a default feature. To accommodate for the change, all
bindings have been updated to select the feature, except for WASM which
has a separate fs implementation.
This also adds some #[cfg] and #[allow] to silence unused-* warnings,
which I discovered when testing with different features disabled.
Closes#942
`sqlite3-parser` spends a lot of time in `yy_reduce` assigning different
`enum YYMINORTYPE` members, and it suffers from bad performance because
the stack size of the enum is very large, and the size of individual
members varies wildly. This PR reduces the `YYMINORTYPE` stack size from
496 to 264 bytes and has the following effect:
Preparing statement:
```sql
Prepare `SELECT 1`/Limbo/SELECT 1
time: [620.37 ns 621.08 ns 621.79 ns]
change: [-17.811% -17.582% -17.380%] (p = 0.00 < 0.05)
Performance has improved.
Prepare `SELECT * FROM users LIMIT 1`/Limbo/SELECT * FROM users LIMIT 1
time: [1.2215 µs 1.2231 µs 1.2248 µs]
change: [-12.926% -12.627% -12.272%] (p = 0.00 < 0.05)
Performance has improved.
Benchmarking Prepare `SELECT first_name, count(1) FROM users GROUP BY first_name HAVING count(1) > 1 ORDER BY cou...: Collecting 100 samples in estimated 5.0152 s (
Prepare `SELECT first_name, count(1) FROM users GROUP BY first_name HAVING count(1) > 1 ORDER BY cou...
time: [3.1056 µs 3.1096 µs 3.1138 µs]
change: [-13.279% -12.995% -12.712%] (p = 0.00 < 0.05)
Performance has improved.
```
Execute (mainly to check for regressions):
```sql
Execute `SELECT * FROM users LIMIT ?`/Limbo/1
time: [402.19 ns 402.75 ns 403.36 ns]
change: [-3.4845% -2.4003% -1.6539%] (p = 0.00 < 0.05)
Performance has improved.
Execute `SELECT * FROM users LIMIT ?`/Limbo/10
time: [2.7920 µs 2.7977 µs 2.8036 µs]
change: [-1.3135% -1.0123% -0.7132%] (p = 0.00 < 0.05)
Change within noise threshold.
Execute `SELECT * FROM users LIMIT ?`/Limbo/50
time: [13.577 µs 13.633 µs 13.690 µs]
change: [-1.7709% -1.3575% -0.9563%] (p = 0.00 < 0.05)
Change within noise threshold.
```
Closes#936