Commit Graph

2324 Commits

Author SHA1 Message Date
sonhmai
2d4bf2eb62 core: move pragma statement bytecode generator to its own file. 2025-02-03 09:21:14 +07:00
Pekka Enberg
593febd9a4 Add Limbo internals doc 2025-02-02 11:42:56 +02:00
Pekka Enberg
dbb7d1a6ba Merge 'Pagecount' from Glauber Costa
This PR implements the Pagecount pragma, as well as its associated
bytecode opcode

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #819
2025-02-02 09:32:18 +02:00
Pekka Enberg
635c45a087 Merge 'Fix null expr codegen' from Nikita Sivukhin
This PR adjust emitted instructions for expressions which include `IS` /
`IS NOT` operators (support for them in the conditions were added in the
#847)

Reviewed-by: Glauber Costa (@glommer)

Closes #857
2025-02-02 09:32:05 +02:00
Pekka Enberg
650b56e203 Merge 'Fix null cmp codegen' from Nikita Sivukhin
This PR remove manual null-comparison optimization (introduced in #847)
which replace `Eq`/`Ne` instructions with explicit `IsNull`/`NotNull`.
There are few factors for this change:
1. Before, manual optimization were incorrect because it ignored
`jump_if_condition_is_true` flag which is important to properly build
logical condition evaluation
2. Manual optimization covered all scenarios in test cases and scenarios
when both sides are non trivial expressions were not covered by tests
3. Limbo already mark literals in the initial emitted bytecode as
constants and will evaluate and store them only once - so performance
difference from manual optimization seems very minor to me (but I am
wrong with high probability)
4. I think (but again, I am wrong with high probability) that such
replacement can be done in the generic optimizator layer instead of
manually encode them in the first emit phase
Fixes #850

Reviewed-by: Glauber Costa (@glommer)

Closes #856
2025-02-02 09:32:00 +02:00
Glauber Costa
a3387cfd5f implement the pragma page_count
To do that, we also have to implement the vdbe opcode Pagecount.
2025-02-01 19:39:46 -05:00
Nikita Sivukhin
1bd8b4ef7a pass null_eq flag for instructions generated for expressions (not in the conditions) 2025-02-02 02:51:51 +04:00
Nikita Sivukhin
4a9292f657 add tests for previously broken case 2025-02-02 02:42:06 +04:00
Nikita Sivukhin
c7aed22e39 null_eq flag disable effect of jump_if_null flag - so it makes no sense to set them both 2025-02-02 02:29:02 +04:00
Nikita Sivukhin
478ee6be8d remove null optimization which didn't check for jump_if_condition_is_true flag
- limbo already store constants only once and more clever optimizations
  better to do with generic optimizator and not manually
2025-02-02 02:28:07 +04:00
Pekka Enberg
20d3399c71 Merge 'implement is and is not where constraints' from Glauber Costa
The main difference between = and != is how null values are handled.
SQLite passes a flag "NULLEQ" to Eq and Ne to disambiguate that.
In the presence of that flag, NULL = NULL.
Some prep work is done to make sure we can pass a flag instead of a
boolean to Eq and Ne. I looked into the bitflags crate but got a bit
scared with the list of dependencies.
Warning:
The following query produces a different result for Limbo:
```
select * from demo where value is null or id == 2;
```
I strongly suspect the issue is with the OR implementation, though. The
bytecode generated is quite different.

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

Closes #847
2025-02-01 17:24:11 +02:00
Pekka Enberg
83f9290394 Merge 'Remove labeler 😥' from Kim Seon Woo
Let's add when we can figure out how to use GH_TOKEN well

Closes #852
2025-02-01 17:23:41 +02:00
김선우
45e0e86516 Remove labeler 😥 2025-02-02 00:04:49 +09:00
Glauber Costa
3c77797811 also mark IS DISTINCT FROM as supported
This seems to really be just an alias for IS:

"The IS NOT DISTINCT FROM operator is an alternative spelling for the IS
operator. Likewise, the IS DISTINCT FROM operator means the same thing
as IS NOT. Standard SQL does not support the compact IS and IS NOT
notation. Those compact forms are an SQLite extension. You have to use
the prolix and much less readable IS NOT DISTINCT FROM and IS DISTINCT
FROM operators on other SQL database engines."
2025-02-01 09:30:06 -05:00
Glauber Costa
c04260ab54 rename Flags to a less ambiguous name
Those Flags in SQLite are global, but it doesn't mean it has to be
the case for us as well.
2025-02-01 08:09:06 -05:00
Pekka Enberg
51f0c9e8a3 Merge 'Full flake overhaul' from Levy A.
Improvements:
- Use [rust-overlay](https://github.com/oxalica/rust-overlay), better
maintained than fenix and allows for:
- Use `rust-toolchain.toml` as the source of truth for the current rust
version, instead of tracking with stable. Preventing conflicting
versions with non-nix users.
- Add flake checks, could be useful for CI in the future, together with
crane and cachix.
- Add package, allow people to add limbo as a regular nix package. Now
we can `nix build .#`, `nix run .#` and `nix shell .#` (this one adds
`limbo` to the current `PATH`)
- Use [new `apple-sdk` pattern](https://discourse.nixos.org/t/the-
darwin-sdks-have-been-updated/55295), no need to declare each framework
now.

Closes #835
2025-02-01 10:34:21 +02:00
Pekka Enberg
a450b5cd39 Update README.md 2025-02-01 09:46:21 +02:00
Pekka Enberg
8c4ef098ef Update README.md 2025-02-01 09:42:13 +02:00
Pekka Enberg
e7f18c4736 Merge 'bindings/go: Progress on Go driver, add sync primitives, prevent crashing on concurrent connections' from Preston Thorpe
This PR continues work on the Go bindings.
- Register all symbols from the library at load time to prevent any
repeated `dlsym` calls.
- Add locks to prevent multiple concurrent FFI calls to functions that
act on the same state.
- Adds documentation/example in the go module `README`.
- Fixes memory access issue causing segfault due to passing pointer to
array of strings, that is difficult to work with in Go without the right
primitives. In place, simply return the amount of ResultColumns and Go
can provide the index to receive the column name, similar to
`rowsGetValue`
On next limbo release, I'll add the example to the main `README` next to
the other language examples. Until then, `go get
github.com/tursodatabase/limbo` will not work so the example will remain
in the bindings readme.

Closes #845
2025-02-01 09:25:52 +02:00
Pekka Enberg
43d6c2760d Merge 'update compat list' from Glauber Costa
Those two expr seem to be supported

Closes #846
2025-02-01 09:24:27 +02:00
Pekka Enberg
db29f43d5c Merge 'Simplify bytecode emitters' from Glauber Costa
Instead of always having the caller specify all instructions, this
    work introduces convenience functions into the program builder,
    making the code a lot cleaner.
    Draft for now, as this is done on top of #841

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

Closes #844
2025-02-01 09:24:11 +02:00
Pekka Enberg
76535d1224 Merge 'github: Configure labeler workflow environment' from Pekka Enberg
This fix was suggested by @seonWKim.

Closes #848
2025-02-01 09:23:53 +02:00
Pekka Enberg
a3ecc69bbb github: Configure labeler workflow environment
This fix was suggested by @seonWKim.
2025-02-01 09:22:17 +02:00
Glauber Costa
96987db6ca implement is and is not where constraints
The main difference between = and != is how null values are handled.
SQLite passes a flag "NULLEQ" to Eq and Ne to disambiguate that.
In the presence of that flag, NULL = NULL.

Some prep work is done to make sure we can pass a flag instead of a
boolean to Eq and Ne. I looked into the bitflags crate but got a bit
scared with the list of dependencies.
2025-01-31 23:01:49 -05:00
PThorpe92
7ee52fca4d bindings/go: update readme with example, change module name 2025-01-31 19:22:21 -05:00
Glauber Costa
f300d2c8e8 rename register for IsNull opcode
Now it has the same name as NotNull, so it is easier to write macros
2025-01-31 19:09:01 -05:00
Glauber Costa
7e8b190b9a update compat list
Those two expr seem to be supported
2025-01-31 16:56:19 -05:00
PThorpe92
8d93130809 bindings/go: enable multiple connections, register all symbols at library load 2025-01-31 13:28:05 -05:00
PThorpe92
950f29daab bindings/go: Adjust tests for multiple concurrent connections 2025-01-31 13:28:05 -05:00
Pekka Enberg
98579ab2e4 Merge 'Implement Noop bytecode' from Pedro Muniz
This PR implements Noop. I really don't know what else to say. This
bytecode according to sqlite does: _Do nothing. Continue downward to the
next opcode._ I advanced the program counter to account for continuing
to the next instruction.

Closes #795
2025-01-31 18:49:54 +02:00
Pekka Enberg
44e5402464 Merge branch 'main' into feature/noop 2025-01-31 18:49:39 +02:00
Glauber Costa
7aa3cc26ad simplify the writing of bytecode programs
Instead of always having the caller specify all instructions, this
work introduces convenience functions into the program builder,
making the code a lot cleaner.
2025-01-31 11:35:51 -05:00
Glauber Costa
b37317f68b avoid allocations during pragma_list
If we keep the pragma list sorted when declaring it, we can avoid
a vector allocation when printing the pragma_list.
2025-01-31 11:35:51 -05:00
Pekka Enberg
d8a9c57d3a Merge 'Fix table with single column PRIMARY KEY to not create extra btree' from Krishna Vishal
The error is due to comparing the PRIMARY KEY's name to INTEGER when in
it was all in lowercase. This was causing `needs_auto_index` to be set
to `true`.
After the fix:
```
/limbo /tmp/sc2-limbo.db
Limbo v0.0.13
Enter ".help" for usage hints.
limbo> CREATE TABLE temp (t1 integer, primary key (t1));

hexdump -s 28 -n 4 /tmp/sc2-limbo.db
000001c 0000 0200 -- matches SQLite
0000020
```
Closes https://github.com/tursodatabase/limbo/issues/824

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

Closes #830
2025-01-31 18:33:28 +02:00
Pekka Enberg
c05b81fdbd Merge 'Pragma list' from Glauber Costa
Closes #841
2025-01-31 18:32:21 +02:00
Glauber Costa
a7cc367c1f implement pragma pragma_list
List all available pragmas (Except pragma_list)
2025-01-31 06:44:56 -05:00
Glauber Costa
62efbde661 use strum package to simplify PragmaName enum management
The pragma list will only grow. The strum crate can be used to:
* automatically convert to string from enum
* automatically convert to enum from string
* implement an iterator over all elements of the enum
2025-01-31 06:44:56 -05:00
Pekka Enberg
e96b649a1a Merge 'github: Use only Python 3.13 for pull request runs' from Pekka Enberg
...speeds up PR cycle time by not running on all the possible Python
configurations all the time.

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #840
2025-01-31 11:41:26 +02:00
Pekka Enberg
3398252ca0 github: Use only Python 3.13 for pull request runs
...speeds up PR cycle time by not running on all the possible Python
configurations all the time.
2025-01-31 11:31:04 +02:00
Pekka Enberg
7f0274e48f Merge 'Table info' from Glauber Costa
This implements the table_info pragma, allowing us to fetch information
about columns present in a table.

Closes #837
2025-01-31 08:46:27 +02:00
Pekka Enberg
053a1acef1 Merge 'Refactor cursor to support multiple state machines' from Alex Miller
This is mostly refactoring Cursor.write_info to instead be an enum,
where one of the options is a WriteInfo.  This permits one to add other
state machines to Cursor, and I added the state needed for Count as an
example, but all the testing for count's implementation depends on
ANALYZE #656 working end-to-end (to some degree) so that one can write a
SQL test for it.
But this code seems conflict-prone, so it seems better to get it in
sooner than later.
I also finally understood what the point of RefCell is from fighting
with rust on this, so that was nice.

Closes #836
2025-01-31 08:45:01 +02:00
Pekka Enberg
a94cd03dfb Merge 'Performance test side by side comparison with rusqlite' from Levy A.
More convenient side by side comparison with sqlite.  Got this idea from
[criterion's documentation](https://bheisler.github.io/criterion.rs/book
/user_guide/comparing_functions.html). Some examples:
<img width="1010" alt="image" src="https://github.com/user-
attachments/assets/1cb400f6-f6a5-44af-a429-8e09a42dcd0d" />
<img width="1002" alt="image" src="https://github.com/user-
attachments/assets/ef35dfa6-6474-4fec-9b78-d81b274f2ca1" />

Closes #839
2025-01-31 08:44:07 +02:00
Pekka Enberg
de45ca82e4 github: Switch labeler to use GH_TOKEN
GITHUB_TOKEN is restricted to read-only by organization rules.
2025-01-31 08:42:24 +02:00
Levy A.
5acd7a5ea8 side by side comparison with sqlite 2025-01-31 03:11:07 -03:00
krishvishal
8b2393fcef Check for if a column is in descending order to add an automatic primary key index. 2025-01-31 08:25:54 +05:30
Glauber Costa
016b815b59 implement pragma table_info
Both () and = variants covered. It is important to make sure that
the transaction is a read transaction, so we cannot hide all that logic
inside update_pragma, and have to make our decision before that.
2025-01-30 20:00:20 -05:00
Glauber Costa
249a8cf8d2 keep type information as a string in column metadata
SQLite holds on to it deeply, for example:

sqlite> create table a(a int);
sqlite> create table b(b integer);
sqlite> create table c(c glauber);

sqlite> pragma table_info=a;
0|a|INT|0||0
sqlite> pragma table_info=b;
0|b|INTEGER|0||0
sqlite> pragma table_info=c;
0|c|glauber|0||0

So we'll keep it as well so we can produce the same responses.
2025-01-30 19:53:36 -05:00
Glauber Costa
f1df43633a change type Display implementation to not show null
This is the behavior that things like pragma table_info seem to
expect.
2025-01-30 19:53:36 -05:00
Alex Miller
9ac52b66d9 Refactor cursor to support multiple state machines 2025-01-30 14:08:44 -08:00
Glauber Costa
69d3fbc797 keep track of notnull constraint on column creation 2025-01-30 17:04:12 -05:00