Previously, queries like:
```
SELECT
CASE WHEN c0 != 'x' THEN group_concat(c1, ',') ELSE 'x' END
FROM t0
GROUP BY c0;
```
would return incorrect results because c0 was not copied during the
aggregation loop into a register accessible to the logic processing the
grouped results (e.g., the CASE WHEN expression in this example).
The same issue applied to expressions in the HAVING and ORDER BY clauses.
Previously, the logic for collecting non-aggregate columns was duplicated
across multiple locations and implemented inconsistently. This caused a
bug that was revealed by the refactoring in this commit (see the added
test).
Currently indexes are the bulk of the problem with `UPDATE` and
`DELETE`, while we work on fixing those it makes sense to disable
indexing since they are not stable. We want to try to make everything
else stable before we continue with indexing.
- `Update` query doesn't update `n_changes`. Let's make it work
- Add `InsertFlags` to add meta information related to insert operations
- For update query, add `UPDATE` flag
- Currently, the update query executes `Insn::Delete` and `Insn::Insert`
internally, it increases `n_change` by 2. So, for the update query,
let's skip increasing `n_change` for the `Insn::Insert`
https://github.com/tursodatabase/limbo/issues/1681
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Closes#1683
This PR adds support for the instruction `IntegrityCk` which performs an
integrity check on the contents of a single table. Next PR I will try to
implement the rest of the integrity check where we would check indexes
containt correct amount of data and some more.
<img width="1151" alt="image" src="https://github.com/user-
attachments/assets/29d54148-55ba-480f-b972-e38587f0a483" />
Closes#1719
also added a `cursor_loop` helper on `ProgramBuilder` to avoid making
this mistake in the future. this is zero-cost, and will be optimized to
the same thing (hopefully).
There's some kind of a bug unrelated to the feature
implemented,
which results in test different results between sqlite3 and limbo
if do_execsql_test_on_specific_db is used to get an error message content.
For example in limbo:
```sql
do_execsql_test_on_specific_db {:memory:} not_null_primary_key {
CREATE TABLE t2 (y INT PRIMARY KEY NOT NULL);
INSERT INTO t2 (y) VALUES (1);
INSERT INTO t2 (y) VALUES (NULL);
SELECT * FROM t2;
} {"Runtime error: NOT NULL constraint failed: t2.y (19)"
1} # notice the 1
```
And in sqlite3 we get
```sql
do_execsql_test_on_specific_db {:memory:} not_null_primary_key {
CREATE TABLE t2 (y INT PRIMARY KEY NOT NULL);
INSERT INTO t2 (y) VALUES (1);
INSERT INTO t2 (y) VALUES (NULL);
SELECT * FROM t2;
} {"Runtime error: NOT NULL constraint failed: t2.y (19)"} # notice the
absense of 1
```
therefore this commit rewrites tests to use do_execsql_test_any_error
instead.
This PR adds support for table-valued functions for PRAGMAs (see the
[PRAGMA functions section](https://www.sqlite.org/pragma.html)).
Additionally, it introduces built-in table-valued functions. I
considered using extensions for this, but there are several reasons in
favor of a dedicated mechanism:
* It simplifies the use of internal functions, structs, etc. For
example, when implementing `json_each` and `json_tree`, direct access to
internals was necessary:
https://github.com/tursodatabase/limbo/pull/1088
* It avoids FFI overhead. [Benchmarks](https://github.com/piotrrzysko/li
mbo/blob/pragma_vtabs_bench/core/benches/pragma_benchmarks.rs) on my
hardware show that `pragma_table_info()` implemented as an extension is
2.5× slower than the built-in version.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1642