Commit Graph

512 Commits

Author SHA1 Message Date
Diego Reis
c4e7be04f8 core: Handles prepared statement with empty SQL 2025-05-12 10:38:58 -03:00
Piotr Rzysko
977b6b331a Fix memory leak caused by unclosed virtual table cursors
The following code reproduces the leak, with memory usage increasing
over time:

```
#[tokio::main]
async fn main() {
    let db = Builder::new_local(":memory:").build().await.unwrap();
    let conn = db.connect().unwrap();

    conn.execute("SELECT load_extension('./target/debug/liblimbo_series');", ())
        .await
        .unwrap();

    loop {
        conn.execute("SELECT * FROM generate_series(1,10,2);", ())
            .await
            .unwrap();
    }
}
```

After switching to the system allocator, the leak becomes detectable
with Valgrind:

```
32,000 bytes in 1,000 blocks are definitely lost in loss record 24 of 24
   at 0x538580F: malloc (vg_replace_malloc.c:446)
   by 0x62E15FA: alloc::alloc::alloc (alloc.rs:99)
   by 0x62E172C: alloc::alloc::Global::alloc_impl (alloc.rs:192)
   by 0x62E1530: allocate (alloc.rs:254)
   by 0x62E1530: alloc::alloc::exchange_malloc (alloc.rs:349)
   by 0x62E0271: new<limbo_series::GenerateSeriesCursor> (boxed.rs:257)
   by 0x62E0271: open_GenerateSeriesVTab (lib.rs:19)
   by 0x425D8FA: limbo_core::VirtualTable::open (lib.rs:732)
   by 0x4285DDA: limbo_core::vdbe::execute::op_vopen (execute.rs:890)
   by 0x42351E8: limbo_core::vdbe::Program::step (mod.rs:396)
   by 0x425C638: limbo_core::Statement::step (lib.rs:610)
   by 0x40DB238: limbo::Statement::execute::{{closure}} (lib.rs:181)
   by 0x40D9EAF: limbo::Connection::execute::{{closure}} (lib.rs:109)
   by 0x40D54A1: example::main::{{closure}} (example.rs:26)
```

Interestingly, when using mimalloc, neither Valgrind nor mimalloc’s
internal statistics report the leak.
2025-05-05 21:26:23 +02:00
pedrocarlo
0c22382f3c shared lock on file and throw ReadOnly error in transaction 2025-05-02 16:30:48 -03:00
meteorgan
d2dce740f7 fix some issues about page_size 2025-04-28 16:13:07 +08:00
meteorgan
0202fa3ed0 add back one comment 2025-04-25 21:57:35 +08:00
meteorgan
f464d15f8b refactor database open_file and open 2025-04-25 21:45:18 +08:00
Levy A.
f1ee92bf2d numeric types overhaul 2025-04-23 08:34:58 -03:00
Timo Kösters
68d8b86bb7 fix: get name of rowid column 2025-04-22 08:46:37 +02:00
PThorpe92
d53c60e071 Prevent double allocations for VFilter args in vdbe 2025-04-17 14:01:45 -04:00
PThorpe92
853af16946 Implement xBestIndex for virtual table api to improve query planning 2025-04-17 13:53:27 -04:00
pedrocarlo
2181de79de add destroy function to vtab 2025-04-13 17:06:12 -03:00
pedrocarlo
000d8756ec Implment VDestroy opcode 2025-04-13 17:06:12 -03:00
Diego Reis
65d4c68cf2 core/pager: Wrap wal with Option 2025-04-13 11:10:05 -03:00
Pekka Enberg
e21e2b5449 Merge 'core: Fix syscall VFS on Linux' from Pekka Enberg
Fix the syscall VFS on Linux not to use `PlatformIO`, which is just an
alias for `io_uring`.

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

Closes #1285
2025-04-09 19:38:45 +03:00
Pekka Enberg
2d009083ba core: Fix syscall VFS on Linux
Fix the syscall VFS on Linux not to use `PlatformIO`, which is just an
alias for `io_uring`.
2025-04-09 19:27:58 +03:00
PThorpe92
6b5ec1f07b Remove mut borrow from sym table in parse schema fn 2025-04-08 20:10:49 -04:00
PThorpe92
c15035caf8 Add module and vtab to schema after table is reopened with proper ext 2025-04-08 20:10:48 -04:00
PThorpe92
4b9b6c969b Parse schema rows after extensions are loaded 2025-04-08 20:10:47 -04:00
Avinash Sajjanshetty
8d6d50d9d5 Update IO trait
- Remove existing `get_current_time() -> String`
- Add super trait bound `Clock`
2025-04-06 23:06:57 +05:30
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
Pere Diaz Bou
ee55116ca6 return row as reference to registers 2025-03-29 22:04:08 +01:00
Pere Diaz Bou
bf37fd3314 wip 2025-03-29 22:02:49 +01:00
Pekka Enberg
387b68fc06 Merge 'Expose 'Explain' to prepared statement to allow for alternate Writer ' from Preston Thorpe
### The problem:
I often need to copy the output of an `Explain` statement to my
clipboard. Currently this is not possible because it currently will only
write to stdout.
All other limbo output, I am able to run `.output file` in the CLI, then
enter my query and in another tmux pane I simply `cat file | xclip -in
-selection clipboard`.
### The solution:
Expose a `statement.explain()` method that returns the query explanation
as a string. If the user uses something like `execute` instead of
prepare, it will default to `stdout` as expected, but this allows the
user to access the query plan on the prepared statement and do with it
what they please.

Closes #1166
2025-03-28 09:55:58 +02:00
Pekka Enberg
df6af6ed79 core: Rename FileStorage to DatabaseFile 2025-03-25 11:15:16 +02:00
PThorpe92
7b55f7a167 Move explain to statement to allow for alternate writer 2025-03-24 18:48:12 -04:00
Diego Reis
16b9325830 ext/python: Basic support for placeholding insert 2025-03-20 17:10:12 -03:00
Diego Reis
2481d73d70 ext/python: Partially implements commit()
It was based on https://docs.python.org/3/library/sqlite3.html but some more work is needed specially in LEGACY_TRANSACTION_CONTROL and isolation levels.

See: https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.autocommit
2025-03-20 17:09:55 -03:00
PThorpe92
57d4aa7216 Reorganize ext library and feature gate vfs to more easily prevent wasm build issues 2025-03-19 10:17:11 -04:00
Pere Diaz Bou
00ab3d1c0c Fix ordering and implement Deref 2025-03-17 10:22:42 +01:00
Pere Diaz Bou
20f5ade95e Experiment with a custom Lock for database header 2025-03-17 10:21:34 +01:00
PThorpe92
2cc72ed9ab Feature flag vfs for fs feature/prevent wasm 2025-03-12 21:52:51 -04:00
PThorpe92
89a08b7611 Add vfslist command and setup CLI with new db open api 2025-03-12 21:52:51 -04:00
PThorpe92
25ed6a2985 Store dynamic ext libs in oncecell to prevent UB 2025-03-12 21:52:50 -04:00
Pere Diaz Bou
2fd790a055 make execute command loop until done 2025-03-12 16:26:29 +01:00
Yirt Grek
bb68fbdd67 bindings/rust: Fix bindings so example runs 2025-03-12 00:54:18 -07:00
Pekka Enberg
d6c514c8d1 core: Integrate MVCC to B-Tree cursor 2025-03-06 10:16:42 +02:00
Pekka Enberg
bf3163c7fe core: Fix parse_schema() to use existing MVCC TX 2025-03-06 10:16:42 +02:00
Pekka Enberg
ef32a82941 core/vdbe: Integrate MVCC transactions 2025-03-06 10:16:42 +02:00
Pekka Enberg
461be0dc87 core: Add multi-version store to Database 2025-03-06 10:16:42 +02:00
Pekka Enberg
96175cccf7 cli: Add --experimental-mvcc option to enable MVCC 2025-03-06 10:16:42 +02:00
Pere Diaz Bou
5f5ca50c41 Move schema lock read to translate only 2025-03-05 14:07:48 +01:00
Pere Diaz Bou
d1c7d758c4 fix uring Sync,Sync unsafe impl 2025-03-05 14:07:48 +01:00
Pere Diaz Bou
47cd54a7fe remove schema comment 2025-03-05 14:07:48 +01:00
Pere Diaz Bou
e20dd59353 Make schema a RWLock
This makes it work like in SQLite where only one schema writer is permitted and readers will return error while preparing statement if the schema is changing.
2025-03-05 14:07:48 +01:00
Pere Diaz Bou
e4a8ee5402 move load extensions to Connection
Extensions are loaded per connection and not per database as per SQLite
behaviour. This also helps with removing locks.
2025-03-05 14:07:48 +01:00
Pere Diaz Bou
0149e86356 add todo comments to remove mutex from database structures 2025-03-05 14:07:48 +01:00
Pere Diaz Bou
8daf7666d1 Make database Sync + Send 2025-03-05 14:07:48 +01:00
PThorpe92
5b8efd92a4 Update extension ownership cleanups for new vtab module 2025-03-01 14:27:33 -05:00
Pekka Enberg
b4e8afa3c7 Merge 'Implement SQLite balancing algorithm' from Pere Diaz Bou
Beep boop.
What happened you ask? I removed the dumb balancing algorithm I
implemented in favor of SQLite's implementation based on B*Tree[1] where
a page is 2/3 full instead of 1/2. It also tries to balance a page by
taking a maximum 3 pages and distributing cells evenly between them.
I've made some changes that are somewhat related:
* Moved most operations on pages out of BTreeCursor because those
operations are based on a page, not on a cursor, and it makes it easier
to test.
* Fixed `write_u16` and `read_u16` cases that didn't need a implicit
offset calculation. Added: `write_u16_no_offset` and
`read_u16_no_offset` to counter this.
* Added some tests with fuzz testing too.
* Fixed some important actions like: `compute_free_space`,
`defragment_page` and `drop_cell`.
[1] https://dl.acm.org/doi/10.1145/356770.356776

Closes #968
2025-02-28 19:10:52 +02:00
Pekka Enberg
936ae307b7 core: Kill value type
We currently have two value types, `Value` and `OwnedValue`. The
original thinking was that `Value` is external type and `OwnedValue` is
internal type. However, this just results in unnecessary transformation
between the types as data crosses the Limbo library boundary.

Let's just follow SQLite here and consolidate on a single value type
(where `sqlite3_value` is just an alias for the internal `Mem` type).
The way this will eventually work is that we can have bunch of
pre-allocated `OwnedValue` objects in `ProgramState` and basically
return a reference to them all the way to the application itself, which
extracts the actual value.
2025-02-26 10:57:45 +02:00