Commit Graph

9385 Commits

Author SHA1 Message Date
Jussi Saurio
433f5a52b1 Disallow ORDER BY and LIMIT in a non-compound VALUES() 2025-09-25 16:30:34 +03:00
Jussi Saurio
c07a227560 Merge 'core/mvcc/logical-log: load logical log from disk' from Pere Diaz Bou
## Description
Read transactions from logical log and load mvcc store based on the
contents onto transaction 0, which is the special transaction where we
will load all row versions that can be read by all new transactions.
## Todo
- [x] Testing for multiple transactions
- [ ] Lock multiple loading of same logical-log at the same time
- [x] Add column_count to format because if not it is hard to judge from
record alone.
- [x] Trim buffer read
I was thinking to implement the rest on another pr to not increase load
to review this one.

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

Closes #3323
2025-09-25 16:26:34 +03:00
Pere Diaz Bou
8f3332377a core/mvcc/logical-log: fmt fmt fmt fmt 2025-09-25 13:33:16 +02:00
Pere Diaz Bou
b75eb9f09d core/mvcc/logical-log: drain consumed bytes on read_more_data 2025-09-25 13:31:03 +02:00
Pere Diaz Bou
7b131b0b0d core/mvcc/logical-log: test fuzz logical log read 2025-09-25 13:23:43 +02:00
Pere Diaz Bou
dd0a71484d core/mvcc/logical-log: test insert 100 transactions 2025-09-25 12:40:05 +02:00
Pere Diaz Bou
8528f92248 core/mvcc/logical-log: fix is_eof 2025-09-25 12:39:48 +02:00
Pere Diaz Bou
654f9a9412 core/mvcc/logical-log: read column_count from immutable record 2025-09-25 12:27:30 +02:00
Jussi Saurio
3113822ceb Merge 'MVCC: support alter table' from Jussi Saurio
Changes ALTER TABLE operations to use only MV store and not go through
pager, because pager is only used during checkpoint.
- Exclusive transaction is required for DDL operations: trying to
execute one inside a `BEGIN CONCURRENT` transaction will return an
error. It's simply too complicated for now to try to make them
concurrently transactional.
- Not doing schema changes via pager means that in MV rollback, the
connection must rollback its private schema separately, since pager
rollback is not invoked.
- To simplify MVCC semantics, if any transaction committed a schema
change after a transaction started, it cannot commit and will abort with
`SchemaUpdated` error
- To mimic regular SQLite transaction behavior, if a transaction tries
to promote to exclusive transaction, it will fail with `Busy` error if
there were any committed transactions after the read transaction
started.

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

Closes #3333
2025-09-25 12:25:22 +03:00
Jussi Saurio
3d38c5a101 mvcc: disallow promote to exclusive tx if another tx committed in between 2025-09-25 11:50:09 +03:00
Jussi Saurio
d4bcf2c15a mvcc: disallow BEGIN after BEGIN CONCURRENT 2025-09-25 11:50:09 +03:00
Jussi Saurio
1ff2e07404 mvcc: disallow BEGIN CONCURRENT after BEGIN 2025-09-25 11:50:09 +03:00
Jussi Saurio
04f9cbfa8d we do not allow DDL inside BEGIN CONCURRENT, so remove test 2025-09-25 11:49:44 +03:00
Jussi Saurio
7c86e7b9c4 merge conflicts with atomics PRs 2025-09-25 11:49:44 +03:00
Jussi Saurio
b12387b2e3 mvcc/fuzz: make some ALTER TABLE ops in mvcc fuzz test 2025-09-25 11:49:18 +03:00
Jussi Saurio
8f46721848 Merge 'Normalize target table name identifier on table or column rename' from Iaroslav Zeigerman
Closes #3320
Closes #3286
In addition to the problem reported in the ticket, 2 more issues were
identified:
1. Renaming a column for a table with a special character in its name
failed with
```
turso> CREATE TABLE `t t`(a);
turso> ALTER TABLE `t t` RENAME COLUMN a TO `a a`;

thread 'main' panicked at core/vdbe/execute.rs:7870:14:
table being renamed should be in schema
```
2. The renamed table in the `sql` column of `sqlite_schema` was not
reflected correctly after renaming:
```
turso>  select * from sqlite_schema;
┌───────┬──────┬──────────┬──────────┬──────────────────────┐
│ type  │ name │ tbl_name │ rootpage │ sql                  │
├───────┼──────┼──────────┼──────────┼──────────────────────┤
│ table │ t t  │ t t      │        2 │ CREATE TABLE t t (a) │
└───────┴──────┴──────────┴──────────┴──────────────────────┘
```
3. `sql` for indexes was not reflected correctly after renaming a column
that contains special characters:
```
turso> ALTER TABLE `t t` RENAME COLUMN `a a` TO `b b`;
turso> SELECT sql FROM sqlite_schema;

┌───────────────────────────────────┐
│ sql                               │
├───────────────────────────────────┤
│ CREATE TABLE `t t` (`b b`)        │
├───────────────────────────────────┤
│ CREATE INDEX idx ON `t t` (`a a`) │
├───────────────────────────────────┤
```

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

Closes #3322
2025-09-25 11:41:45 +03:00
Pekka Enberg
b81cc1da1d Merge 'Fix: NULL values in group_concat()' from
Closes #3304.
group_concat() now ignores null values.

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

Closes #3321
2025-09-25 10:19:41 +03:00
Jussi Saurio
54a566967c Merge 'Fix result columns binding precedence' from Jussi Saurio
In e.g. `SELECT x AS y, y AS x FROM t ORDER BY x;`, the `x` in the
`ORDER BY` should reference t.y, which has been aliased as `x` for this
query. The same goes for GROUP BY, JOIN ON etc. but NOT for WHERE.
Previously we had wrong precedence in `bind_and_rewrite_expr`.
Closes #3281

Closes #3290
2025-09-25 09:26:24 +03:00
Jussi Saurio
ede2a882f1 mvcc: revert connection schema changes in mv rollback 2025-09-25 08:43:00 +03:00
Jussi Saurio
1626ef046b mvcc: abort tx if other tx made a schema change in between 2025-09-25 08:43:00 +03:00
Jussi Saurio
864fa379dd mvcc: require exclusive transaction for schema changes 2025-09-25 08:42:59 +03:00
Jussi Saurio
b37ddc208f Merge 'mvcc: add blocking checkpoint' from Jussi Saurio
mvcc: add blocking checkpoint
    performs a blocking, truncating checkpoint:
    - when started, blocks any other transactions from starting
    - writes all row versions to pager that havent already been
      checkpointed
    - flushes them to wal
    - checkpoints wal to db
    in the case of added/deleted rows in table id 1 (sqlite schema),
    also creates/destroys btrees accordingly

Closes #3263
2025-09-25 08:42:43 +03:00
Iaroslav Zeigerman
4799f23261 Fix: Normalize the target table name identifier when renaming a table / column 2025-09-24 22:23:04 -07:00
Pekka Enberg
a27257f7d8 Merge 'use a different seed for gen_rng' from Pedro Muniz
Because `InteractionPlan::init_plan` and `gen_rng` used an rng with the
same seed initially, it could happen that we could create the first
create query in `init_plan`, and then generate a `DoubleCreateFailure`
property that would generate the exact same previous query, due to the
seed being the same. The easy and quick fix is just to use different
seeds.
Closes #3330
Closes #3329
Closes #3327
Closes #3326
Closes #3325
Closes #3324

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

Closes #3331
2025-09-25 08:19:15 +03:00
Jussi Saurio
49602f409f fixes after atomics merge conflicts 2025-09-25 08:16:52 +03:00
Jussi Saurio
f7806cbc33 mvcc: add basic checkpoint test 2025-09-25 08:12:13 +03:00
Jussi Saurio
3010dc0255 mvcc: add CheckpointStateMachine
performs a blocking, truncating checkpoint:

- when started, blocks any other transactions from starting
- writes all row versions to pager that havent already been
  checkpointed
- flushes them to wal
- checkpoints wal to db

in the case of added/deleted rows in table id 1 (sqlite schema),
also creates/destroys btrees accordingly
2025-09-25 08:12:13 +03:00
Jussi Saurio
429f305fe8 mvcc: add MvStore::get_next_table_id()
this assigns "synthetic" root page numbers instead of using the pager
or btree cursors to allocate pages. Actual page allocation will only
happen during checkpoint, since regular MVCC commit bypasses the
pager.
2025-09-25 08:12:13 +03:00
Jussi Saurio
b702af8ac0 mvcc: add truncate method to logical log 2025-09-25 08:12:13 +03:00
Jussi Saurio
8f33b31c3d mvcc: update global header on commit end 2025-09-25 08:12:13 +03:00
Jussi Saurio
7464d1c172 mvcc: remove tx from store when commit write set is empty
previously, this was leaking transaction IDs in the mv store.
2025-09-25 08:12:13 +03:00
Jussi Saurio
949e6dd728 mvcc: remove unused states and fields from CommitStateMachine
none of the pager commit related data and logic are used anymore,
so let's delete them.
2025-09-25 08:12:12 +03:00
Jussi Saurio
c18c44b032 fix: result columns have varying binding precedence
In e.g. `SELECT x AS y, y AS x FROM t ORDER BY x;`, the `x` in the
`ORDER BY` should reference t.y, which has been aliased as `x` for this
query. The same goes for GROUP BY, JOIN ON etc. but NOT for WHERE.

Previously we had wrong precedence in `bind_and_rewrite_expr`.
2025-09-25 08:07:37 +03:00
Pekka Enberg
0a78ea87d5 Merge 'core: Wrap Connection::attached_databases with RwLock' from Pekka Enberg
Closes #3310
2025-09-25 07:46:48 +03:00
Pekka Enberg
11288619af Merge 'Add built-in manual pages for Turso' from Glauber Costa
In the hopes of doing a good job at teaching people what Turso can do, I
am adding built-in manual pages. When the CLI starts, it picks a feature
at random, and tells the user that the feature exists:
```
Turso v0.2.0-pre.8
Enter ".help" for usage hints.
Did you know that Turso supports Change Data Capture? Type .manual cdc to learn more.
This software is ALPHA, only use for development, testing, and experimentation.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database
```
There is a lot we can do to make this feature world class:
- we can automatically compile examples during compile time like rust-
doc, to make sure examples used in the manuals always work
- we can implement scrolling and navigation
- we can document a lot more features
But for now, this is a start!

Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #3298
2025-09-25 07:46:40 +03:00
pedrocarlo
4cbf861699 use a different seed for gen_rng 2025-09-25 01:20:35 -03:00
Pere Diaz Bou
1478538cb9 core/mvcc/logical-log: load logical log from disk
Read transactions from logical log and load mvcc store based on the
contents onto transaction 0, which is the special transaction where we
will load all row versions that can be read by all new transactions.

- [ ] Testing for multiple transactions
- [ ] Lock multiple loading of same logical-log at the same time
- [ ] Add column_count to format because if not it is hard to judge from
record alone.
2025-09-25 02:15:28 +02:00
Pere Diaz Bou
74f0830920 Merge 'core/mvcc/logical-log: on disk format for logical log' from Pere Diaz Bou
This format is based on previous discussions:
1. Log header
```rust
/// Log's Header, this will be the 64 bytes in any logical log file.
/// Log header is 64 bytes at maximum, fields added must not exceed that size. If it doesn't exceed
/// it, any bytes missing will be padded with zeroes.
struct LogHeader {
    version: u8,
    salt: u64,
    encrypted: u8, // 0 is no
}
```
2. Transaction format:
* Transaction id
* Checksum u64
* Byte size of all rows combined
* Rows
* End marker (offset position after appending buffer)
3. Row format:
```rust
    /// Serialize a row_version into on disk format.
    /// Format of a "row" (maybe we could change the name because row is not general enough for
    /// future type of values):
    ///
    /// * table_id (root page) -> u64
    /// * row type -> u8
    ///
    /// (by row type)
    /// Delete:
    /// * Payload length -> u64
    /// * Rowid -> varint
    ///
    /// Insert:
    /// * Payload length -> u64
    /// * Data size -> varint
    /// * Rowid -> varint
    /// * Data -> [u8] (data size length)
    fn serialize(&self, buffer: &mut Vec<u8>, row_version: &RowVersion) {

```

Closes #3245
2025-09-25 00:39:03 +02:00
rajajisai
b9ef9d6c63 Ignore null values in group concat 2025-09-24 18:11:02 -04:00
Pekka Enberg
456bd619b8 Merge 'Wrap more Connection fields with atomics' from Pekka Enberg
Closes #3307
2025-09-24 20:16:42 +03:00
Pekka Enberg
f8f23a2a15 core: Wrap Connection::attached_databases with RwLock 2025-09-24 20:15:58 +03:00
Pekka Enberg
03263a9977 core: Wrap Connection::data_sync_retry with AtomicBool 2025-09-24 19:30:31 +03:00
Pekka Enberg
60e9d1a1c4 core: Wrap Connection::is_nested_stmt in AtomicBool 2025-09-24 19:30:31 +03:00
Pekka Enberg
a50771fe38 core: Wrap Connection::query_only with AtomicBool 2025-09-24 19:23:13 +03:00
Pekka Enberg
465dba573d core: Wrap Connection::closed with AtomicBool 2025-09-24 19:15:13 +03:00
Pekka Enberg
84588c03a8 Merge 'core/mvcc: Wrap Transaction::database_header with RwLock' from Pekka Enberg
Closes #3296
2025-09-24 19:14:22 +03:00
Pekka Enberg
eaddf1030d Merge 'core: Wrap Connection::capture_data_changes in RwLock' from Pekka Enberg
Closes #3293
2025-09-24 19:14:15 +03:00
Glauber Costa
fbc3d0dbc3 Add built-in manual pages for Turso
In the hopes of doing a good job at teaching people what Turso can do,
I am adding built-in manual pages. When the CLI starts, it picks a
feature at random, and tells the user that the feature exists:

```
Turso v0.2.0-pre.8
Enter ".help" for usage hints.
Did you know that Turso supports Change Data Capture? Type .manual cdc to learn more.
This software is ALPHA, only use for development, testing, and experimentation.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database
```

There is a lot we can do to make this feature world class:
- we can automatically compile examples during compile time like
  rust-doc, to make sure examples used in the manuals always work
- we can implement scrolling and navigation
- we can document a lot more features

But for now, this is a start!
2025-09-24 11:29:24 -03:00
Preston Thorpe
0511183abc Merge 'Fix program counter update in sequence test op' from Preston Thorpe
it's not emitted anywhere yet but still saw this bug

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

Closes #3297
2025-09-24 10:01:01 -04:00
Pekka Enberg
3f11badf24 Merge 'antithesis-tests: Rename "utils.py" to "helper_utils.py"' from Pekka Enberg
Antithesis is now supposed to detect that this is not a runnable driver
and not complain about it.

Closes #3294
2025-09-24 15:31:24 +03:00