Commit Graph

10048 Commits

Author SHA1 Message Date
Nikita Sivukhin
14e104f830 add convert operation 2025-10-09 16:56:36 +04:00
Nikita Sivukhin
8584ee18a3 refactor parsing/deserialization 2025-10-09 16:36:39 +04:00
Nikita Sivukhin
a2f4376bd2 move more operations to the operations/ folder 2025-10-09 16:18:53 +04:00
Nikita Sivukhin
7e9e102f20 move vector operations under operations/ folder 2025-10-09 16:02:03 +04:00
Nikita Sivukhin
5b6e8e4b84 Float32/Float64 -> Float32Dense/Float64Dense 2025-10-09 13:28:40 +04:00
Jussi Saurio
acb3c97fea Merge 'When pwritev fails, clear the dirty pages' from Pedro Muniz
If we don't clear the dirty pages, we will initiate a rollback. In the
rollback, we will attempt to clear the whole page cache, but it will
then panic because there will still be dirty pages from the failed
writev

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

Closes #3189
2025-10-09 10:38:47 +03:00
Pekka Enberg
e3144a74aa Merge 'Add Nightly versions of benchmarks that run on Nyrkiö runners' from Henrik Ingo
Nyrkiö is piloting a GitHub Runner service, and congratulations, you are
the pilot customer! In order to reduce the risk somewhat, we'll
introduce this as a parallel workflow, so the existing benchmarks will
continue to run on the regular runners and they won't have any
discontinuity in their results because of this. Also since these runners
are actually a bit more expensive, we can manage the cost by only
running them periodically. Similarly, this allows us to fine tune the
Nyrkiö instance size, for example to have an EBS disk that is the
optimal size and IOPS configuration, so you don't pay for empty space.
I will show up in discord to discuss.
And congratulations on the beta release by the way! I worked hard to get
this done for your beta period, let's hope it works now.

Closes #3619
2025-10-09 10:09:57 +03:00
Pere Diaz Bou
f06ee571be Merge 'MVCC: Don't modify the row version chain on rollback' from Duy Dang
Rollback shouldn't modify the row version chain. This is crucial for
implementing a Non-blocking row version chain in #3499

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

Closes #3583
2025-10-08 18:00:02 +02:00
Pekka Enberg
08cf663d7b Merge 'Add support for sqlite_version() star syntax' from Glauber Costa
SQLite surprisingly supports this:
select sqlite_version(*);
this gets translated at the parser level to sqlite_version(), and it
works for all functions that take 0 arguments.
Let's be compatible with SQLite and support the same thing.

Closes #3630
2025-10-08 17:41:27 +03:00
Pekka Enberg
3c525219a2 Merge 'mvcc: Disable automatic checkpointing by default' from Pekka Enberg
MVCC checkpointing currently prevents concurrent writes so disable it by
default while we work on it.

Closes #3631
2025-10-08 17:09:37 +03:00
Duy Dang
4fe3282d8e Fix missing let from merge 2025-10-08 21:06:13 +07:00
Duy Dang
f7b3033a09 Merge branch 'main' into rollback-fix 2025-10-08 20:56:54 +07:00
Pekka Enberg
17a578a496 bindings/rust: Tokio is not required
The bindings use just async Rust so any async runtime should work.
2025-10-08 11:47:39 +03:00
Pekka Enberg
d8fc548b7f Merge 'Fix rusqlite compatibility claim' from Dave Warnock
Make it clear that the Turso rust binding is not a drop-in replacement
for rusqlite. Turso is async and rusqlite isn't

Closes #3633
2025-10-08 11:47:10 +03:00
Jussi Saurio
06bc90bffe Merge 'core/translate: implement basic foreign key constraint support' from Preston Thorpe
This PR introduces support for foreign key constraints, and the `PRAGMA
foreign_keys;`, and relevant opcodes: `FkCounter` and `FkIfZero`.
Extensive fuzz tests were added both for regular and composite
PK/rowid/unique index constraints, as well as some really weird
edgecases to make sure we our affinity handling is correct as well when
we trigger the constraints.
Foreign-key checking is driven by two VDBE ops: `FkCounter` and
`FkIfZero`, and
 `FkCounter` is a running meter on the `Connection` for deferred FK
violations. When an `insert/delete/update` operation creates a potential
orphan (we insert a child row that doesn’t have a matching parent, or we
delete/update a parent that children still point at), this counter is
incremented. When a later operation fixes that (e.g. we insert the
missing parent or re-target the child), we decrement the counter. If any
is remaining at commit time, the commit fails. For immediate
constraints, on the violation path we emit Halt right away.
`FkIfZero` can either be used to guard a decrement of FkCounter to
prevent underflow, or can potentially (in the future) be used to avoid
work checking if any constraints need resolving.
NOTE: this PR does not implement `pragma defer_foreign_keys` for global
`deferred` constraint semantics. only explicit `col INT REFERENCES t(id)
DEFERRABLE INITIALLY DEFERRED` is supported in this PR.
This PR does not add support for `ON UPDATE|DELETE CASCADE`, only for
basic implicit `DO NOTHING` behavior.
~~NOTE: I did notice that, as referenced here: #3463~~
~~our current handling of unique constraints does not pass fuzz tests, I
believe only in the case of composite primary keys,~~ ~~because the fuzz
test for FK referencing composite PK is failing but only for UNIQUE
constraints, never (or as many times as i tried) for foreign key
constraints.~~
EDIT: all fuzzers are passing, because @sivukhin fixed the unique
constraint issue.
The reason that the `deferred` fuzzer is `#[ignore]`'d is because sqlite
uses sub-transactions, and even though the fuzzing only does 1 entry per
transaction... the fuzzer can lose track of _when_ it's in a transaction
and when it hits a FK constraint, and there is an error in both DB's, it
can just continue to do run regular statements, and then the eventual
ROLLBACK will revert different things in sqlite vs turso.. so for now,
we leave it `ignore`d

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

Closes #3510
2025-10-08 11:44:24 +03:00
Dave Warnock
e28ece6950 Update Doc regarding rusqlite compatibility
Make it clear that it's not a drop in replacement for rusqlite as that
isn't async
2025-10-08 08:03:43 +01:00
Pekka Enberg
f92d19ddeb Tweak README a bit 2025-10-08 09:20:44 +03:00
Pekka Enberg
94c343770d mvcc: Disable automatic checkpointing by default
MVCC checkpointing currently prevents concurrent writes so disable it by
default while we work on it.
2025-10-08 09:14:55 +03:00
Glauber Costa
111b6fcb81 support the same syntax as sqlite for version function
SQLite surprisingly supports this:

select sqlite_version(*);

this gets translated at the parser level to sqlite_version(), and it
works for all functions that take 0 arguments.

Let's be compatible with SQLite and support the same thing.
2025-10-07 23:00:56 -07:00
Pekka Enberg
13566e5cad Merge 'Integrity check enhancements' from Jussi Saurio
- add index root pages to list of root pages to check
- check for dangling (unused) pages
```sql
$ cargo run wut.db 
turso> .mode list
turso> pragma integrity_check;
Page 3: never used
Page 4: never used
Page 7: never used
Page 8: never used
```
```sql
$ sqlite3 wut.db 'pragma integrity_check;'
*** in database main ***
Page 3: never used
Page 4: never used
Page 7: never used
Page 8: never used
```

Closes #3613
2025-10-08 08:57:18 +03:00
PThorpe92
7e9277958b Fix deferred FK in vdbe 2025-10-07 16:45:23 -04:00
PThorpe92
a232e3cc7a Implement proper handling of deferred foreign keys 2025-10-07 16:45:23 -04:00
PThorpe92
f56f37fae5 Add more tests for self-referencing FKs and remove unneeded FkIfZero checks/labels in emitter 2025-10-07 16:45:23 -04:00
PThorpe92
99ae96c5f6 Fix self-referential FK relationships and validation of FKs 2025-10-07 16:45:22 -04:00
PThorpe92
fa23cedbbe Add helper to pragma to parse enabled opts and fix schema parsing for foreign key constraints 2025-10-07 16:45:22 -04:00
PThorpe92
23248d9001 Add UPSERT to fuzzing for FK constraints 2025-10-07 16:45:22 -04:00
PThorpe92
37c8abf247 Fix schema representation and methods for ForeignKey resolution 2025-10-07 16:45:22 -04:00
PThorpe92
ae975afe49 Remove unnecessary FK resolution on schema parsing 2025-10-07 16:45:16 -04:00
PThorpe92
16d19fd39e Add tcl tests for foreign keys 2025-10-07 16:28:04 -04:00
PThorpe92
2db18f8230 Add fk_fuzzing sql file to .gitignore 2025-10-07 16:28:04 -04:00
PThorpe92
346e6fedfa Create ForeignKey, ResolvedFkRef types and FK resolution 2025-10-07 16:27:49 -04:00
Henrik Ingo
223b060a6a Increase instance size to avoid OOM 2025-10-07 23:26:19 +03:00
PThorpe92
c2b7026131 Add FOREIGN_KEY constraint error 2025-10-07 16:22:20 -04:00
PThorpe92
d04b07b8b7 Add pragma foreign_keys and fk_if_zero and fk_counter opcodes 2025-10-07 16:22:20 -04:00
PThorpe92
b40e784903 Update COMPAT.md, add fk related opcodes 2025-10-07 16:22:15 -04:00
Jussi Saurio
8bdef12e15 Merge 'Remove unsafe pointers (RawSlice) from RefValue' from Levy A.
- 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
2025-10-07 22:42:52 +03:00
Jussi Saurio
1cef12ef73 Merge 'Simulator: Add Drop and pave the way for Schema changes' from Pedro Muniz
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
2025-10-07 22:41:53 +03:00
pedrocarlo
300d918040 fix differential check for parse error 2025-10-07 15:03:50 -03:00
pedrocarlo
3b2583c540 adjust Interaction generation to take into account possibilty of PropertyDistribution to have 0 Weights 2025-10-07 14:17:37 -03:00
pedrocarlo
c578f7ba96 Faultless should produce any type of query, just not faulty 2025-10-07 14:15:51 -03:00
pedrocarlo
21fc8bae2a Property::FaultyQuery and FsyncNoWait stored a list of tables to check the on the database. Again, the FaultyQuery could be a Drop Table which meant that we could be running a SELECT on an inexistent table. To solve this, just insert a Property that check all the tables in the db after a Faulty Property 2025-10-07 13:23:35 -03:00
pedrocarlo
6bad5d04ce generate extensional queries when iterating over the next interaction, not when generating the property. This is necessary as the extensional queries can modify schema and thus could cause the next queries to fail because the DB enviroment context was not updated on generation time. Rule of thumb: queries should never be generated in bulk, always one a a time so the enviroment can be shadowed accordingly 2025-10-07 13:19:53 -03:00
pedrocarlo
6d5443d4f0 add Query::Placeholder 2025-10-07 11:38:47 -03:00
pedrocarlo
7eb504baef certain properties cannot be generated if there are no tables in the current context 2025-10-07 11:38:47 -03:00
pedrocarlo
07cc1c548b adjust query generation to avoid DROP for certain extensional queries 2025-10-07 11:38:47 -03:00
pedrocarlo
4fc7be5042 as we have DROP table now, if we want to generate extensional queries eagerly, without affecting how we document interactions with MVCC, we need to travel forward in time and shadow queries eagerly so we can generate queries correctly. This involves cloning the tables unfortunately which is inneficient but correct 2025-10-07 11:38:47 -03:00
pedrocarlo
3e8867c8f5 DropSelect property should only fail when error is not a parse error on the table name 2025-10-07 11:38:47 -03:00
pedrocarlo
7f93f64fc5 enable Drop statements 2025-10-07 11:38:47 -03:00
Pekka Enberg
ff67c1f3ca Merge 'Make table name not repeat in simulator' from bit-aloo
closes: #3254

Closes #3617
2025-10-07 17:04:23 +03:00
Levy A.
cf53ecb7e3 refactor: remove TextRef and RawSlice and fix tests 2025-10-07 10:43:45 -03:00