Commit Graph

2937 Commits

Author SHA1 Message Date
Jussi Saurio
f599b5a752 Make programbuilder aware of plan to count/estimate required memory 2025-02-05 14:22:42 +02:00
Pekka Enberg
f772fc83e1 core/mvcc: Disable test_overlapping_concurrent_inserts_read_your_writes test
...it fails sporadically
2025-02-05 14:18:56 +02:00
Pekka Enberg
56d401fb67 Merge 'Implement json_set' from Marcus Nilsson
This PR adds support for `json_set`.
There are three helper functions added:
1. `json_path_from_owned_value`, this function turns an `OwnedValue`
into a `JsonPath`.
2. `find_or_create_target`, this function is similar to `find_target`
with the added bonus of creating the target if it doesn't exist. There
is a caveat with this function and that is that it will create
objects/arrays as it goes, meaning if you send `{}` into it and try
getting the path `$.some.nested.array[123].field`, it will return
`{"some":{"nested":array:[]}}` since creation of `some`, `nested` and
`array` will succeed, but accessing element `123` will fail.
3. `create_and_mutate_json_by_path`, this function is very similar to
`mutate_json_by_path` but calls `find_or_create_target` instead of
`find_target`

Related to #127

Closes #878
2025-02-05 14:15:02 +02:00
Pekka Enberg
acb98f56d5 core/mvcc: Thanks Clippy... 2025-02-05 13:44:55 +02:00
Pekka Enberg
36b487d281 core/mvcc: Make Clippy happy 2025-02-05 13:41:20 +02:00
Pekka Enberg
5870c92e9e core/mvcc: Fix MVCC benchmark SIGKILL
The `begin_tx` benchmark makes no sense because it just fills up memory with
transaction metadata, eventually killing the process...
2025-02-05 13:33:38 +02:00
Pekka Enberg
44ca85e121 core: Enable MVCC benchmark 2025-02-05 13:26:05 +02:00
Pekka Enberg
fad479ac59 core/mvcc: Move source code to module 2025-02-05 13:25:16 +02:00
Pekka Enberg
a585b81148 mvcc/core: Kill S3 persistent storage 2025-02-05 12:51:58 +02:00
Pekka Enberg
e923a2352e core/mvcc: Kill mvcc-rs crate
We'll just integrate everything in the core.
2025-02-05 12:50:46 +02:00
Pekka Enberg
9f0b33a8ef core/mvcc: Remove README.md 2025-02-05 12:50:46 +02:00
Pekka Enberg
5c9bb4bddd core/mvcc: Remove duplicate Cargo workspace config 2025-02-05 12:42:39 +02:00
Pekka Enberg
5e282c00bc Remove duplicate MIT license 2025-02-05 12:42:15 +02:00
Pekka Enberg
7d99894269 Move MVCC docs to top-level docs directory 2025-02-05 12:41:55 +02:00
Pekka Enberg
df20213a4b core/mvcc: Remove C bindings
We won't need them because we just use the Rust APIs in the core.
2025-02-05 12:40:28 +02:00
Pekka Enberg
fcb4c7e46a core/mvcc: Remove Git metadata files 2025-02-05 12:40:06 +02:00
Pekka Enberg
b9568b74af Merge "Hekaton MVCC implementation" from Pekka and others
This imports the full history of the following Git repository into
`core/mvcc` directory as-is:

https://github.com/penberg/tihku/tree/main
2025-02-05 12:38:35 +02:00
Pekka Enberg
9fdf54de2b Merge 'Small perf optimizations to statement preparation' from Jussi Saurio
```bash
Prepare `SELECT 1`/Limbo/SELECT 1
                        time:   [765.94 ns 768.26 ns 771.03 ns]
                        change: [-7.8340% -7.4887% -7.1406%] (p = 0.00 < 0.05)
                        Performance has improved.

Prepare `SELECT * FROM users LIMIT 1`/Limbo/SELECT * FROM users LIMIT 1
                        time:   [1.5673 µs 1.5699 µs 1.5731 µs]
                        change: [-10.810% -9.7122% -8.4951%] (p = 0.00 < 0.05)
                        Performance has improved.

Prepare `SELECT first_name, count(1) FROM users GROUP BY first_name HAVING count(1) > 1 ORDER BY cou...
                        time:   [4.1331 µs 4.1421 µs 4.1513 µs]
                        change: [-9.3157% -9.0255% -8.7372%] (p = 0.00 < 0.05)
                        Performance has improved.
```
flamegraph for prepare `SELECT 1`:
<img width="1718" alt="Screenshot 2025-02-03 at 10 34 14"
src="https://github.com/user-
attachments/assets/ba67fe2f-78b2-4796-9a09-837d8e79fe62" />

Closes #872
2025-02-05 10:46:57 +02:00
Pekka Enberg
0b0681c9f8 core/vdbe: Lazy cursor borrowing
This saves a few more nanoseconds:

```
Execute `SELECT 1`/Limbo
                        time:   [44.964 ns 45.064 ns 45.160 ns]
                        change: [-14.371% -13.724% -13.214%] (p = 0.00 < 0.05)
                        Performance has improved.
```
2025-02-05 09:47:17 +02:00
Pekka Enberg
23cd8b10c3 core: Unify StepResult structs
...also simplify Statement::step() to get some performance back.

Before:

```
Execute `SELECT 1`/Limbo
                        time:   [49.128 ns 50.425 ns 52.604 ns]
```

After:

```
Execute `SELECT 1`/Limbo
                        time:   [49.128 ns 50.425 ns 52.604 ns]
```
2025-02-05 09:09:32 +02:00
Pekka Enberg
7573fc62e6 core: Unify Row and Record structs
They're exactly the same thing.
2025-02-05 09:04:52 +02:00
Marcus Nilsson
01492cf46f add support for json_set
Test cases are included.
Related to #127
2025-02-04 19:09:58 +01:00
Marcus Nilsson
3478352b18 move extraction of JsonPath from OwnedValue to separate function 2025-02-04 17:49:49 +01:00
Pekka Enberg
e4d7474372 core: Switch to parking_lot for RwLock
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]
```
2025-02-04 18:38:33 +02:00
Pekka Enberg
750164fb85 Merge 'Sqlean Time extension' from Pedro Muniz
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.md

Closes #854
2025-02-04 18:27:44 +02:00
Pekka Enberg
733f7de688 Merge branch 'main' into feature/time-ext 2025-02-04 18:27:14 +02:00
Pekka Enberg
f69804969c Merge 'Adding checkpoint result' from Sonny
### 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
2025-02-04 18:26:24 +02:00
Pekka Enberg
a045866a6c Merge 'core: Fix benchmark panic if syscall is interrupted' from Pekka Enberg
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
2025-02-04 18:25:34 +02:00
Pekka Enberg
bf1ef13c91 Merge 'Add Printf Support' from Zaid Humayun
Add basic printf function support in limbo
![Screenshot 2025-02-04 at 8 08 23 PM](https://github.com/user-
attachments/assets/b12931eb-8e79-4c8a-af77-c25c34cc5834)

Closes #886
2025-02-04 17:53:27 +02:00
Zaid Humayun
6a863b3da9 printf: this commit adds support for https://github.com/tursodatabase/limbo/issues/885 tracking printf functionality
this commit introduces basic support for printf functionality and doesn't include advanced modifiers like width etc.
2025-02-04 20:05:14 +05:30
Pekka Enberg
31552f0862 core/json: Kill some unwrap() calls 2025-02-04 14:55:19 +02:00
Pekka Enberg
2d9a54ccba Merge 'implement json_pretty' from Pedro Muniz
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
2025-02-04 14:51:47 +02:00
Pekka Enberg
0050f4aeea Merge 'Support column aliases in GROUP BY, ORDER BY and HAVING' from Jussi Saurio
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
2025-02-04 14:51:05 +02:00
Pekka Enberg
b4a3cadf58 Merge 'Improve in-memory IO performance, remove runtime borrow checking' from Preston Thorpe
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
2025-02-04 14:50:38 +02:00
Pekka Enberg
097e56c19f core: Kill Statement::query() method
It's a pointless wrapper on top of `step()` that introduce additional
memory allocation and deallocation.
2025-02-04 13:46:11 +02:00
Pekka Enberg
7dbfdba59f core: Fix benchmark panic if syscall is interrupted
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
2025-02-04 13:24:55 +02:00
Pekka Enberg
fb0a560d76 Merge 'dont store insn comments unless the query is EXPLAIN' from Jussi Saurio
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
2025-02-04 13:10:37 +02:00
Pekka Enberg
da96072780 Merge 'Lower ownership requirement for Value' from Levy A.
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
2025-02-04 13:10:10 +02:00
Levy A.
9df0b01689 refactor: lower ownership requirement 2025-02-03 16:52:42 -03:00
Jussi Saurio
1f888fea4f Dont fsync the WAL on read queries 2025-02-03 20:42:50 +02:00
Jussi Saurio
d182ddf514 dont store insn comments unless the query is EXPLAIN 2025-02-03 19:53:33 +02:00
sonhmai
022a8d7a83 core: return checkpoint result 2025-02-03 19:02:16 +07:00
sonhmai
1c803aa079 feat: add wal checkpoint result 2025-02-03 18:57:22 +07:00
Jussi Saurio
750a9c6463 assertions and small cleanups 2025-02-03 13:08:13 +02:00
Jussi Saurio
8b1f0ea23c Use vec for label resolution, not hashmap 2025-02-03 12:52:15 +02:00
Jussi Saurio
40f536fabb Dont store available_indexes on plan; only used in optimize_plan() 2025-02-03 12:52:14 +02:00
Jussi Saurio
61a007fb29 preallocate plan.result_columns according to AST 2025-02-03 12:51:24 +02:00
Jussi Saurio
f2dab8499d preallocate loop metadata according to table/column count and prefer vec over hashmap 2025-02-03 12:51:24 +02:00
Jussi Saurio
d4cb0a1223 Merge 'Fix logical codegen' from Nikita Sivukhin
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
2025-02-03 12:39:41 +02:00
Jussi Saurio
d41dfd0c5d Merge 'Fix rowid search codegen' from Nikita Sivukhin
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
2025-02-03 12:38:04 +02:00