We really need to make the WAL lock less expensive, but switching to
`parking_lot` is anyway something we should do.
Before:
```
Execute `SELECT 1`/Limbo
time: [56.230 ns 56.463 ns 56.688 ns]
```
After:
```
Execute `SELECT 1`/Limbo
time: [52.003 ns 52.132 ns 52.287 ns]
```
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#887
I socially engineerd Jamie into generating a Turso branded cover image
by merging something he hated, which was AI-generated image of a dark
forest. Thanks Jamie!
We really need to make the WAL lock less expensive, but switching to
`parking_lot` is anyway something we should do.
Before:
```
Execute `SELECT 1`/Limbo
time: [56.230 ns 56.463 ns 56.688 ns]
```
After:
```
Execute `SELECT 1`/Limbo
time: [52.003 ns 52.132 ns 52.287 ns]
```
This PR implements a sqlean time compatible extension. I would
appreciate some help to review my code and see if there are ways to
enhance it. Also, if there is some edge case, I have missed please tell
me.
https://github.com/nalgeon/sqlean/blob/main/docs/time.mdCloses#854
### What?
adding checkpoint result returning number of pages in wal and num pages
checkpointed.
Part of #696
### Context
SQLite returns in checkpoint result of calling `pragma wal_checkpoint;`
`0|3|3` while limbo returns `0|0|0`.
https://sqlite.org/pragma.html#pragma_wal_checkpoint
- 1st col: 1 (checkpoint SQLITE_BUSY) or 0 (not busy).
- 2nd col: # modified pages written to wal file
- 3rd col: # pages moved to db after checkpoint
This PR aims to add 2nd and 3rd column to the checkpoint result.
SQLite
```
sqlite3 test.db
sqlite> pragma journal_mode=wal;
wal
sqlite> pragma journal_mode;
wal
sqlite> create table t1 (id text);
sqlite> insert into t1(id) values (1),(2);
sqlite> select * from t1;
1
2
sqlite> pragma wal_checkpoint;
0|3|3
```
Limbo
```
./target/debug/limbo test.db
Limbo v0.0.13
Enter ".help" for usage hints.
limbo> pragma journal_mode;
wal
limbo> create table t1(id text);
limbo> insert into t1(id) values (1),(2);
limbo> select * from t1;
1
2
# current the 2nd and 3rd columns are hard coded in limbo to 0
limbo> pragma wal_checkpoint;
0|0|0
```
Closes#827
Fixes the following panics:
Benchmarking Execute `SELECT * FROM users LIMIT ?`/Limbo/100: Profiling
for 5.0000 sthread 'main' panicked at core/benches/benchmark.rs:69:43:
called `Result::unwrap()` on an `Err` value: IOError(Os { code: 4, kind:
Interrupted, message: "Interrupted system call" })
note: run with `RUST_BACKTRACE=1` environment variable to display a
backtrace
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#882
Add basic printf function support in limbo

Closes#886
This PR implements json_pretty. At the moment, support for jsonb is
being added, so this function suffers from the same limitations as in
json(x). Also, I have not found a way to implement the same conversion
of Blob -> String that SQLite does. From my own experimentation, I
believe SQLite converts blobs to a lossy ascii representation, but I
would appreciate some help on this.
Closes#860
Closes#744
```sql
# Wanda = 9, Whitney = 11, William = 111
do_execsql_test column_alias_in_group_by_order_by_having {
select first_name as fn, count(1) as fn_count from users where fn in ('Wanda', 'Whitney', 'William') group by fn having fn_count > 10 order by fn_count;
} {Whitney|11
William|111}
```
Closes#864
Despite likely replacing this in-memory IO setup in the near future with
a `mmap` implementation (#859) , in the spirit of everyone getting
bitten by the perf bug lately I thought I would speed up our in-memory
IO a bit.
Closes#861
Fixes the following panics:
Benchmarking Execute `SELECT * FROM users LIMIT ?`/Limbo/100: Profiling for 5.0000 sthread 'main' panicked at core/benches/benchmark.rs:69:43:
called `Result::unwrap()` on an `Err` value: IOError(Os { code: 4, kind: Interrupted, message: "Interrupted system call" })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
We spend a lot of time especially in `GROUP BY` queries providing
helpful comments for `EXPLAIN`, even when the query is not an `EXPLAIN`.
So let's not do that
Closes#784
```sql
Prepare `SELECT first_name, count(1) FROM users GROUP BY first_name HAVING count(1) > 1 ORDER BY cou...
time: [4.2724 µs 4.2783 µs 4.2848 µs]
change: [-6.1063% -5.7376% -5.3626%] (p = 0.00 < 0.05)
Performance has improved.
```
doesn't affect the other trivial prepare benchmarks
Closes#875
If you have a `&str` you would need to allocate and copy the string just
to pass a reference to it again. Same goes if you have a slice of bytes.
In all (most?) situations, that is not what you want and sometimes
impossible to satisfy. Example:
```rs
impl From<&str> for Value<'_> {
fn from(value: &str) -> Self {
Self::Text(&value.to_owned())
}
}
```
Here, there is no way to pass a reference to a `String` without making
the lifetime `'static`, since the string has to be dropped by the end of
the function or leaked. I would consider this a anti-pattern. There is
no reason to keep a shared reference to a owned value. (And can't think
of any situation where you would need such thing)
Now, this is possible:
```rs
impl<'a> From<&'a str> for Value<'a> {
fn from(value: &'a str) -> Self {
Self::Text(value)
}
}
```
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#838
Fix few logical codegen issues and add fuzz tests for logical
expressions
- Right now Limbo fails to recognize `false` constant in case when any
unary operator is used on the AST path. This PR add unary operator
option in the rewrite code and handle such cases properly.
```sql
limbo> SELECT NOT FALSE;
× Parse error: no such column: FALSE - should this be a string literal in single-quotes?
```
- `ifnull` implementation produced incorrect codegen due to "careless"
management of registers
```
limbo> SELECT ifnull(0, NOT 0)
[NULL here]
```
- `like` implementation produced incorrect codegen due to "careless"
management of registers
```
limbo> SELECT like('a%', 'a') = 1;
thread 'main' panicked at core/vdbe/mod.rs:1902:41:
internal error: entered unreachable code: Like on non-text registers
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
Depends on https://github.com/tursodatabase/limbo/pull/867 (need
`GrammarGenerator` from this branch)
Closes#869
This PR fixes a bug when index search used incorrect operator if index
column were the "rhs" in the expression (not "lhs" as usual, e.g.
`SELECT * FROM t WHERE 1 < rowid_alias`)
Reviewed-by: Jussi Saurio (@jussisaurio)
Closes#870