We'd love to have you contribute to Limbo!
This document is a quick helper to get you going.
Limbo is a rewrite of SQLite in Rust. If you are new to SQLite, the following articles and books are a good starting point:
- Architecture of SQLite
- Sibsankar Haldar. SQLite Database System Design and Implementation (2nd Edition). 2016
- Jay Kreibich. Using SQLite: Small. Fast. Reliable. Choose Any Three. 1st Edition. 2010
If you are new to Rust, the following books are recommended reading:
- Jim Blandy et al. Programming Rust, 2nd Edition. 2021
- Steve Klabnik and Carol Nichols. The Rust Programming Language. 2022
Examples of contributing
The issue tracker has issues tagged with good first issue, which are considered to be things to work on to get going. If you're interested in working on one of them, comment on the issue tracker, and we're happy to help you get going.
Fork the repository and open a pull request to submit your work.
The CI checks for formatting, Clippy warnings, and test failures so remember to run the following before submitting your pull request:
cargo fmt
andcargo clippy
to keep the code formatting in check.make
to run the test suite.
Keep your pull requests focused and as small as possible, but not smaller. IOW, when preparing a pull request, ensure it focuses on a single thing and that your commits align with that. For example, a good pull request might fix a specific bug or a group of related bugs. Or a good pull request might add a new feature and test for it. Conversely, a bad pull request might fix a bug, add a new feature, and refactor some code.
The commits in your pull request tell the story of your change. Break your pull request into multiple commits when needed to make it easier to review and ensure that future developers can also understand the change as they are in the middle of a git bisect
run to debug a nasty bug. A developer should be able to reconstruct the intent of your change and how you got to the end-result by reading the commits. To keep a clean commit history, make sure the commits are atomic:
- Keep commits as small as possible. The smaller the commit, the easier it is to review, but also easier
git revert
when things go bad. - Don't mix logic and cleanups in same commit. If you need to refactor the code, do it in a commit of its own. Mixing refactoring with logic changes makes it very hard to review a commit.
- Don't mix logic and formatting changes in same commit. Resist the urge to fix random formatting issues in the same commit as your logic changes, because it only makes it harder to review the commit.
- Write a good commit message. You know your commit is atomic when it's easy to write a short commit message that describes the intent of the change.
To produce pull requests like this, you should learn how to use Git's interactive rebase (git rebase -i
).
For a longer discussion on good commits, see Al Tenhundfeld's What makes a good git commit, for example.
Limbo aims towards SQLite compatibility. If you find a query that has different behavior than SQLite, the first step is to check what the generated bytecode looks like.
To do that, first run the EXPLAIN
command in sqlite3
shell:
sqlite> EXPLAIN SELECT first_name FROM users;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 7 0 0 Start at 7
1 OpenRead 0 2 0 2 0 root=2 iDb=0; users
2 Rewind 0 6 0 0
3 Column 0 1 1 0 r[1]= cursor 0 column 1
4 ResultRow 1 1 0 0 output=r[1]
5 Next 0 3 0 1
6 Halt 0 0 0 0
7 Transaction 0 0 1 0 1 usesStmtJournal=0
8 Goto 0 1 0 0
and then run the same command in Limbo's shell.
If the bytecode is different, that's the bug -- work towards fixing code generation. If the bytecode is the same, but query results are different, then the bug is somewhere in the virtual machine interpreter or storage layer.
The testing/test.all
is a starting point for adding functional tests using a similar syntax to SQLite.
The purpose of these tests is to verify behavior matches with SQLite and Limbo.
- Cargo-c is needed for building C-ABI compatible library. You can get it via:
cargo install cargo-c
- SQLite is needed for compatibility checking. You can install it using
brew
on macOS/Linux:
brew install sqlite
Or using choco
on Windows:
choco install sqlite
To run the test suite with Limbo, simply run:
make test
To run the test suite with SQLite, type:
SQLITE_EXEC=sqlite3 SQLITE_FLAGS="" make test
When working on a new feature, please consider adding a test case for it.
TPC-H is a standard benchmark for testing database performance. To try out Limbo's performance against a TPC-H compatible workload, you can generate or download a TPC-H compatible SQLite database e.g. here.
The simulator
directory contains a deterministic simulator for testing.
What this means is that the behavior of a test run is deterministic based on the seed value.
If the simulator catches a bug, you can always reproduce the exact same sequence of events by passing the same seed.
The simulator also performs fault injection to discover interesting bugs.