- Add a lifetime parameter to `RefValue`, improving safety semantics by
preventing invalid pointers to `ImmutableRecord`.
- Also renames `RefValue` to `ValueRef`, to align with rusqlite and
other crates.
- Improve ergonomics by removing `RawSlice` in favor of native slices
Making it easier and safer to implement
https://github.com/tursodatabase/turso/issues/2304.
`TextSubtype` is stored as part of the enum variant of `ValueRef::Text`,
but this will be changed in a more general reworking of subtyping
described in https://github.com/tursodatabase/turso/issues/3573
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#3587
Depends on #3585
Some properties can have extensional queries that run in between the
queries that the property aims to prove. These queries were generated
eagerly together with the generation of the `Property`. This was okayish
when we were not generating `Drop` queries, however with `Drop`
statements in the game we could generate queries that reference dropped
tables.
Example:
- Drop Table t;
- Select * from t;
The example above was possible because we update the simulator model
only after we run the query, so we could generate queries with stale
data.
**WHAT CHANGED**
- Stop generating queries eagerly in `Property`.
- Introduce `Query::Placeholder` to signify that the `Query` should be
generated in `PlanGenerator::next`. We then swap `Query::Placeholder`
with whatever query we generate
- This change is still compatible with MVCC as we still generate
`Commit` queries when `PlanGenerator` encounters a `DDL` statement
- Add `Property::AllTablesHaveExpectedContent` to check the tables in
the DB after a Faulty property executes, instead of pre selecting the
tables we want to check. We need to do this because a `FaultyQuery` may
Drop a table, resulting in a ParseError later on in the checks.
PS: In commit[`3c85040b4a483f4160d7324e664782a112a6a7a3`](https://github
.com/tursodatabase/turso/commit/3c85040b4a483f4160d7324e664782a112a6a7a3
), for correctness, I thought we had to clone the Simulator Tables every
time we wanted to generate extensional queries. However, later on I
reused the code of that commit and found a solution that could
generalize easier to any type of schema change. This will make it easier
for me add `ALTER TABLE` next.
Closes#3605
op_destroy was assuming we never yield IO from
BTreeCursor::btree_destroy(), so every so often it would just not
complete the procedure and leave dangling pages in the database
Closes#3608Closes#3618
op_destroy was assuming we never yield IO from BTreeCursor::btree_destroy(),
so every so often it would just not complete the procedure and leave
dangling pages in the database
Yield is a completion that does not allocate any inner state. By design
it is completed from the start and has no errors. This allows lightly
yield without allocating any locks nor heap allocate inner state.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#3616
Yield is a completion that does not allocate any inner state. By design
it is completed from the start and has no errors. This allows lightly
yield without allocating any locks nor heap allocate inner state.
Yield is a completion that does not allocate any inner state. By design
it is completed from the start and has no errors. This allows lightly
yield without allocating any locks nor heap allocate inner state.
I simplified `Interactions` generation code to first check the possible
queries we can generate and then create a Weighted Distribution to
generate `Query` and `Property`. This change allows us to not generate
certain types of queries if we have no tables, as it is not sound for
the Simulator to generate an `Update` query if there are no tables in
the database. I made this change for correctness and because I want to
introduce schema changes to the simulator and this is necessary.
Also, there is the additional benefit of us allocating less memory,
doing static function dispatch instead of creating closures all the time
for generation, and the code, in my opinion, being more readable.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Reviewed-by: bit-aloo (@Shourya742)
Closes#3585
This PR add proper program abort in case of unfinished statement reset
and interruption.
Also, this PR makes rollback methods non-failing because otherwise of
their callers usually unclear (if rollback failed - what is the state of
statement/connection/transaction?)
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#3591
There is currently a bug found in our materialized view implementation
that happens when we delete a row, and then re-insert another row with
the same primary key.
Our insert code needs to detect updates and generate a DELETE + INSERT.
But in this case, after the initial DELETE, the fresh insert generates
another delete.
We ended up with the wrong response for aggregations (and I am pretty
sure even filter-only views would manifest the bug as well), where
groups that should still be present just disappeared because of the
extra delete.
A new test case is added that fails without the fix.
Closes#3601