We're now mixing different error messages, which makes compatibility
testing pretty hard. Unify on a single, SQLite compatible error message
"no such table".
When an `UPDATE` statement modifies a table's `INTEGER PRIMARY KEY`
(which acts as a `rowid` alias) alongside other indexed columns, the
index entries were incorrectly retaining the old `rowid`. This led to
stale index references, causing subsequent queries to return incorrect
results.
This change ensures that when the `rowid` alias is part of the `SET`
clause in an `UPDATE` statement, the new `rowid` value is used for
generating and updating index records. This guarantees that all index
entries correctly point to the updated row, resolving the data
inconsistency.
Fixes#1897Closes#1916
When an `UPDATE` statement modifies a table's `INTEGER PRIMARY KEY` (which acts as a `rowid` alias) alongside other indexed columns, the index entries were incorrectly retaining the old `rowid`. This led to stale index references, causing subsequent queries to return incorrect results.
This change ensures that when the `rowid` alias is part of the `SET` clause in an `UPDATE` statement, the new `rowid` value is used for generating and updating index records. This guarantees that all index entries correctly point to the updated row, resolving the data inconsistency.
Closes#1888 . This PR fixes UPDATE translation by not emitting an
ephemeral plan when we are doing a `RowIdEq` search. Also, we should
delete the previous rowid when the rowid is in the set clause.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1891
Previously, the `jump_if_condition_is_true` flag was not respected. As a
result, for expressions like <`ISNULL`/`NOTNULL`> `OR` <rhs>, the <rhs>
expression was evaluated even when the left-hand side was true, and its
value was incorrectly used as the final result.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1846
Previously, the `jump_if_condition_is_true` flag was not respected. As a
result, for expressions like <`ISNULL`/`NOTNULL`> `OR` <rhs>, the <rhs>
expression was evaluated even when the left-hand side was true, and its
value was incorrectly used as the final result.
Previously, with the `index_experimental` feature enabled, the query in
the added test would enter an infinite loop. This happened because
`label_grouping_agg_step` pointed to a constant argument that was moved
to the end of the program. As a result, the aggregation loop would jump
to the constant, then return to the start of the main loop, rewind the
index, and re-enter the aggregation loop—causing it to repeat
indefinitely.
This PR initializes an UV project in `antithesis_tests` so that we can
have an easier time to track dependencies and build pylimbo
automatically for our environment. Consequently, making it easier to
create new antithesis tests in the future with better IDE support.
Also modified our Github actions to check python linting with Ruff, and
removed unnecessary Python jobs. With that, I applied the Ruff fixes
which is the cause of the many file changes.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1782
Fixes DELETE not emitting conditional jumps at all if the associated
WhereTerm is a constant, e.g.
```sql
limbo> create table t(x);
limbo> explain DELETE FROM t WHERE 5-5;
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 7 0 0 Start at 7
1 OpenWrite 0 2 0 0 root=2; t
2 Rewind 0 6 0 0 Rewind table t
3 RowId 0 1 0 0 r[1]=t.rowid
4 Delete 0 0 0 0
5 Next 0 3 0 0
6 Halt 0 0 0 0
7 Transaction 0 1 0 0 write=true
8 Goto 0 1 0 0
```
I was adding more stuff to the simulator in a Branch of mine, and I
caught this error with delete. Upstreaming the fix here. As we do with
Update, I added the translation step for the `WhereTerms` of the query.
Edit: Closes#1732. Closes#1733. Closes#1734. Closes#1735. Closes
#1736. Closes#1738. Closes#1739. Closes#1740.
Edit: Also pushes constant where term translation to `init_loop` for
Update and Select as well.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1746
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