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
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. Please consider:
- Running
cargo fmt
andcargo clippy
to keep the code formatting in check. - Running
make
to run the test suite.
As general guideline for pull requests, please:
- Don't mix fixes and cleanups in same pull request. They just increase the likelhood of merge conflicts. Cleanups are welcome, but just keep them separate.
- Prefer
git rebase main
overgit merge main
on your branches to keep git logs clean.
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.
To run the test suite with Limbo, simply run:
make test
To run the test suite with SQLite, type:
SQLITE_EXEC=sqlite3 make test
When working on a new feature, please consider adding a test case for it.
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.