There are two bugs in #1085.
1. `find_free_cell` accesses non-existent free blocks and returns their
size to `allocate_space`. This is out of range access error. The fix is
to add a loop termination condition that stops it when we hit the end of
the blocks
2. This bug is caused by `find_free_cell` some how swallowing the blocks
with size `4 bytes`. So `compute_free_space` consistently undercounts by
`4 bytes`. I've refactored that part of the code to make sure 4 sized
block are not deleted.
I've also added a unit test which proves these fixes work and also added
a function called `debug_print_freelist` which prints all free blocks of
a page.
For now I've silenced the `overflow_page` tests.
Fixes#1085Closes#1111
You might have guessed the `DumbLruCache` was dumb, but no, it was a
reference to myself. This PR fixes some dumb mistakes of detaching nodes
which failed to update `tail` and `head` properly.
Edit: This PR now fixes `Connection::execute` which funnily enough we
didn't notice it was returning successfully but in reality
`program.step` returned `IO` which made us think it was finished but not
really.
Edit 2: This PR fixes yet another thing! Pages read from WAL where being
initialized as if they were `id > 1`. By making it not this dumb thing
we can read `page 1` from `WAL` without failing catastrophically
Closes#1115
When I added frame reading support I thought, okay, who cares about the page id of this page it we read it from a frame because we don't need it to compute the offset to read from the file in this case. Fuck me, because it was needed in case we read `page 1` from WAL because it has a differnt `offset`.
Previously any block that has a size 4 is deleted resulting in the issue of computed free space
is less than 4 bytes when compared to expected free space.
This PR introduces test for SQLite3 API implementation, adding both unit
tests in Rust and maintaining existing C compatibility tests.
## Changes
- Added unit tests for core SQLite3 operations in `lib.rs`:
- Database initialization and shutdown
- Memory database operations
- Error code handling and messages
- Statement preparation and execution
- Version information verification
Closes#1108
This PR adds support for `DROP TABLE` and addresses issue
https://github.com/tursodatabase/limbo/issues/894
It depends on https://github.com/tursodatabase/limbo/pull/785 being
merged in because it requires the implementation of `free_page`.
EDIT: The PR above has been merged.
It adds the following:
* an implementation for the `DropTable` AST instruction via a method
called `translate_drop_table`
* a couple of new instructions - `Destroy` and `DropTable`. The former
is to modify physical b-tree pages and the latter is to modify in-memory
structures like the schema hash table.
* `btree_destroy` on `BTreeCursor` to walk the tree of pages for this
table and place it in free list.
* state machine traversal for both `btree_destroy` and
`clear_overflow_pages` to ensure performant, correct code.
* unit & tcl tests
* modifies the `Null` instruction to follow SQLite semantics and accept
a second register. It will set all registers in this range to null. This
is required for `DROP TABLE`.
The screenshots below have a comparison of the bytecodes generated via
SQLite & Limbo.
Limbo has the same instruction set except for the subroutines which
involve opening an ephemeral table, copying over the triggers from the
`sqlite_schema` table and then re-inserting them back into the
`sqlite_schema` table.
This is because `OpenEphemeral` is still a WIP and is being tracked at
https://github.com/tursodatabase/limbo/pull/768


Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Closes#897
This pull request integrates MVCC with the VDBE.
The long term plan is to implement SQLite `BEGIN CONCURRENT` by
introducing a "MV store" abstraction (that implements the Hekaton in-
memory MVCC index) above the pager. Traditional SQLite transactions use
the pager and the WAL, but MV store has its own transaction path that
updates the in-memory multi-versioned index. If a key does not exist in
the MVCC index, we read records from the pager. When a MVCC transaction
commits, we emit WAL entries.
In this pull request, we wire up the MVCC transaction machinery to VDBE
and multi-version cursor to the b-tree cursor. Currently, the database
either runs in normal b-tree mode or in in-memory MVCC, but we need to
explore if we can make it a hybrid solution where you can read from both
MVCC index and B-Tree. Note that this pull request also does not add
logical logging to a file, which is something we'll defer for later.
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Closes#917