Commit Graph

8807 Commits

Author SHA1 Message Date
Piotr Rzysko
6d84cbedc2 Fix delimiter handling in group_concat and string_agg
Non-literal delimiters must be translated by AggArgumentSource.
2025-09-13 10:49:14 +02:00
Piotr Rzysko
110ffba2a1 Fix accumulator reset when arguments outnumber aggregates
Previously, while resetting accumulator registers, we would also
reset subsequent registers. This happened because the number of registers
to reset was computed as the sum of arguments rather than the number of
aggregate functions.
2025-09-13 10:49:14 +02:00
Piotr Rzysko
6224cdbbd3 Support WalkControl in walk_expr_mut
Now walk_expr_mut can use WalkControl to skip parts of the expression
tree. This makes it consistent with walk_expr.
2025-09-13 10:49:14 +02:00
Piotr Rzysko
b911e80607 Add AggValue instruction
Adds the AggValue instruction, which computes the current aggregate
result and writes it to a dedicated destination register.

Unlike AggFinal, it does not overwrite or clear the accumulator
register. This makes it possible to retrieve aggregate results multiple
times—needed when processing window functions—while preserving the
accumulator state.
2025-09-13 10:49:14 +02:00
Piotr Rzysko
c5a12f52c2 Don't mutate state in op_agg_final
Previously, only the External and Avg aggregates mutated state during
AggFinal. This is unnecessary because AggFinal runs only once per group,
so caching the result provides no performance benefit.

By avoiding state mutation, we can also reuse op_agg_final for the
AggValue instruction that will be added soon.
2025-09-13 10:49:14 +02:00
Piotr Rzysko
458172220e Remove unused method from AggContext 2025-09-13 10:49:14 +02:00
Piotr Rzysko
867bef55d8 Add ResetSorter instruction
This instruction isn't used yet, but it will be needed for window
functions, since they heavily rely on ephemeral tables.
2025-09-13 10:44:56 +02:00
Piotr Rzysko
ea9599681e Add OpenDup instruction
The instruction isn’t used yet, but it’ll be needed for window functions,
since they heavily rely on ephemeral tables.
2025-09-13 10:35:33 +02:00
Preston Thorpe
b1420904bb Merge 'fix(btree): advance cursor after interior node replacement in delete' from Jussi Saurio
## Problem
When a delete replaces an index interior cell, the replacement key is LT
the deleted key. Currently on the main branch, after the deletion
happens, the following call to BTreeCursor::next() stops at the replaced
interior cell.
This is incorrect - imagine the following sequence:
- We are executing a query that deletes all keys WHERE key > 5
- We delete <key=6> from an interior node, and take a replacement
<key=5> from the left subtree of that interior page
- next() is called, and we land on the interior node again, which now
has <key=5>, and we incorrectly delete it even though our WHERE
condition is key > 5.
## Solution
This PR:
- Tracks `interior_node_was_replaced` in CheckNeedsBalancing
- If no balancing is needed and a replacement occurred, advances once so
the next invocation of next() will skip the replaced cell properly
i.e. we prevent next() from landing on the replaced content and ensures
iteration continues with the next logical record.
## Details
This problem only became apparent once we started using indexes as valid
iteration cursors for DELETE operations in #2981
Closes #3045

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #3049
2025-09-12 17:37:01 -04:00
Pekka Enberg
1803d0bb5d test: Enable some MVCC test cases
Suggested by Jussi
2025-09-12 23:11:45 +03:00
Pekka Enberg
ad6157028e Merge 'core/vdbe: Fix BEGIN CONCURRENT transactions' from Pekka Enberg
The transaction upgrade logic in Transaction opcode is total nonsense
for concurrent transactions so just drop it.
Fixes #3061

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #3070
2025-09-12 23:11:12 +03:00
Pekka Enberg
a0921c4221 Merge 'core/storage: Remove unused import warning' from Pekka Enberg
Closes #3069
2025-09-12 23:11:05 +03:00
Pekka Enberg
5e2b1bc0d3 Merge 'Fix incompatible math functions' from Levy A.
Fixes #1817, #2068, #1326, #1397.
The solution is very much not ideal, but fixes all math function related
incompatibilities.

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

Closes #3033
2025-09-12 21:28:08 +03:00
Pekka Enberg
86dcdad3d0 core/vdbe: Fix BEGIN CONCURRENT transactions
The transaction upgrade logic in Transaction opcode is total nonsense
for concurrent transactions so just drop it.

Fixes #3061
2025-09-12 21:19:34 +03:00
Pekka Enberg
2bc8c0c850 core/storage: Remove unused import warning 2025-09-12 21:09:38 +03:00
Pekka Enberg
dcd43ab8fc Merge 'Handle EXPLAIN QUERY PLAN like SQLite' from Lâm Hoàng Phúc
After this PR:
```
turso> EXPLAIN QUERY PLAN SELECT 1;
QUERY PLAN
`--SCAN CONSTANT ROW
turso> EXPLAIN QUERY PLAN SELECT 1 UNION SELECT 1;
QUERY PLAN
`--COMPOUND QUERY
   |--LEFT-MOST SUBQUERY
   |  `--SCAN CONSTANT ROW
   `--UNION USING TEMP B-TREE
      `--SCAN CONSTANT ROW
turso> CREATE TABLE x(y);
turso> CREATE TABLE z(y);
turso> EXPLAIN QUERY PLAN SELECT * from x,z;
QUERY PLAN
|--SCAN x
`--SCAN z
turso> EXPLAIN QUERY PLAN SELECT * from x,z ON x.y = z.y;
QUERY PLAN
|--SCAN x
`--SEARCH z USING INDEX ephemeral_z_t2
turso>
```

Closes #3057
2025-09-12 20:41:23 +03:00
Pekka Enberg
b2d0de796b Merge 'Fix simulator docker build chef by adding whopper directory' from Preston Thorpe
Closes #3068
2025-09-12 20:40:42 +03:00
PThorpe92
02743253ee Fix simulator docker build chef by adding whopper directory 2025-09-12 13:35:02 -04:00
Preston Thorpe
1752266285 Merge 'Update epoch on each checkpoint to prevent using stale pages for backfilling' from Preston Thorpe
Using this epoch that gets incremented on each checkpoint, combined with
snapshotting the page, allows us to use cached pages during even passive
mode (without the write lock), because we check again after the snapshot
that the page is still valid.
https://github.com/tursodatabase/turso/pull/3053#issuecomment-3285093103
This PR also removes the `WalFile` copy of the `WalHeader`, to prevent
us forgetting that it exists and using potentially stale data, and adds
`checkpoint_seq` atomic to WalFile to help us determine whether the log
has changed and a read tx snapshot is stale.

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

Closes #3058
2025-09-12 12:54:00 -04:00
PThorpe92
b04c364981 Fix clippy error 2025-09-12 11:43:38 -04:00
Pekka Enberg
5df05e05f8 Turso 0.2.0-pre.3 2025-09-12 18:40:06 +03:00
Pekka Enberg
9c08095abf Merge 'fix wasm-runtime package.json' from Nikita Sivukhin
Closes #3066
2025-09-12 18:39:49 +03:00
PThorpe92
7a14c7394f Remove the header copy stored on the WalFile, fix fast_path 2025-09-12 11:29:43 -04:00
PThorpe92
25e7c719f1 Update checkpoint_seq on each checkpoint, not just when log restarts
This was causing checkpoint_seq to be 0 when we had already successfully
ran a passive checkpoint, and causing us to use improper pages from the
cache.
2025-09-12 11:29:42 -04:00
Nikita Sivukhin
99759b9efd fix wasm-runtime package.json 2025-09-12 19:28:30 +04:00
Pekka Enberg
2651b597c6 Turso 0.2.0-pre.2 2025-09-12 17:38:30 +03:00
Pekka Enberg
14da283e36 Merge 'MVCC: remove reliance on BTreeCursor::has_record()' from Jussi Saurio
Closes #3051
Closes #3032

Closes #3056
2025-09-12 17:31:15 +03:00
Pekka Enberg
54b4c9f30b Merge 'Implement the balance_quick algorithm' from Jussi Saurio
Fast balancing routine for the common special case where the rightmost
leaf page of a given subtree overflows such that the overflowing cell
would be the rightmost cell on the page -- i.e. an append. In this case
we just add a new leaf page as the right sibling of that page, put the
overflow cell there, and insert a new divider cell into the parent. The
high level steps are:
1. Allocate a new leaf page and insert the overflow cell payload in it.
2. Create a new divider cell in the parent - it contains the page number
of the old rightmost leaf, plus the largest rowid on that page.
3. Update the rightmost pointer of the parent to point to the new leaf
page.
4. Continue balance from the parent page (inserting the new divider cell
may have overflowed the parent

Closes #3041
2025-09-12 17:30:52 +03:00
Pekka Enberg
443720c74a Merge 'benchmark: introduce simple 1 thread concurrent benchmark for mvcc/sq…' from Pere Diaz Bou
…lite/wal
This is considerably simpler with 1 thread as we just try to yield
control when I/O happens and we only run io.run_once when all
connections tried to do some work. This allows connections to
cooperatively progress.

Closes #3060
2025-09-12 17:27:41 +03:00
Pekka Enberg
7fdb116d41 Merge 'core/mvcc: queue mvcc txns on pager's end_tx' from Pere Diaz Bou
Flushing mvcc changes to disk requires serialization. To do so we simply
introduce a lock for pager.end_tx, which will take ownership of flushing
to WAL. Once this is finished we can simply release lock.
When multiple tx writes happen concurrently in mvcc, max frame will be
updated. This new max_frame makes is the point of view of the other
transaction return busy because his current wal snapshot is outdated.

Closes #3059
2025-09-12 17:27:17 +03:00
Pere Diaz Bou
ec2cff2026 benchmark: introduce simple 1 thread concurrent benchmark for mvcc/sqlite/wal
This is considerably simpler with 1 thread as we just try to yield
control when I/O happens and we only run io.run_once when all
connections tried to do some work. This allows connections to
cooperatively progress.
2025-09-12 14:02:57 +00:00
Pere Diaz Bou
39fb5913e0 core/mvcc: queue write txn commits in mvcc on pager end_tx
Flushing mvcc changes to disk requires serialization. To do so we simply
introduce a lock for pager.end_tx, which will take ownership of flushing
to WAL. Once this is finished we can simply release lock.
2025-09-12 14:00:02 +00:00
Pere Diaz Bou
e87226548c core/mvcc: fix concurrent tests mvcc 2025-09-12 13:49:40 +00:00
Pere Diaz Bou
9b6d181be4 wal: add hacky update max frame for mvcc use
When multiple tx writes happen concurrently in mvcc, max frame will be
updated. This new max_frame makes is the point of view of the other
transaction return busy because his current wal snapshot is outdated.
2025-09-12 13:49:14 +00:00
Pere Diaz Bou
66b5630870 vdbe/mvcc: rollback mvcc txn on vdbe error 2025-09-12 13:47:45 +00:00
Jussi Saurio
b5f3da100b Merge 'fix CI for apple builds' from Nikita Sivukhin
Intel MAC builds were removed in https://github.com/tursodatabase/turso/
commit/3547bd10931e030a372bedb4968404301c2936c6 but arm builds were
broken after that.
This PR returns back proper ARM builds for Apple

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

Closes #3054
2025-09-12 16:19:05 +03:00
Jussi Saurio
6559f23f85 Merge 'hack imports of wasm due to the issues in Vite and Next.js build systems' from Nikita Sivukhin
This tries to establish smooth as possible experience for browser
packages in web.
In order to do that this PR do the following tricks:
1. export `./vite` entry-point which should be used like `import {
connect } from "@tursodatabase/database-browser/vite"` for Vite bundler
   * This entrypoint has fix for the issue
https://github.com/vitejs/vite/issues/8427 which breaks package in the
dev-server mode
   * In order to overcome this we do 2 tricks:
     - Inline WASM module in order to avoid loading it from the separate
file
     - Use same file as entry-point for main thread and for the web
worker
   * Note, that we do these tricks only for `development` build and
produce build will be chunked and optimized as usual with Vite and will
treat worker and WASM modules as separate fiels
3. export `./turbopack` entry-point which should be used like `import {
connect } from @tursodatabase/database-browser/turbopack"` for Turbopack
(Next.js) bundler
   * This entrypoint has fix for the issue
https://github.com/vercel/next.js/issues/82520'
   * In order to overcome this for now we always inline WASM for Next.js
4. Bundle browser libraries in order to easily consume them without need
for bundlers:
   * e.g. `import { connect } from
"https://unpkg.com/@tursodatabase/database-browser/bundle/main.es.js";`
5. We vendor `@napi-rs/wasm-runtime` for now in order to fix runtime
errors due to accesses to `process.env.NODE_DEBUG_NATIVE` env var (not
defined in web)
   * This should be very temporary solution because I already fixed
wasm-util dependency which cause this error
(https://github.com/toyobayashi/wasm-util/issues/4) and hope that napi-
rs PR will be merged soon: https://github.com/napi-rs/napi-rs/pull/2921

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

Closes #3017
2025-09-12 16:18:47 +03:00
Jussi Saurio
305b2f55ae MVCC: remove reliance on BTreeCursor::has_record() 2025-09-12 16:03:55 +03:00
Jussi Saurio
ff23f9795b Merge 'Fix tests for views' from Preston Thorpe
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #3053
2025-09-12 16:03:43 +03:00
Nikita Sivukhin
78e06ff4f7 fix update script 2025-09-12 17:03:04 +04:00
TcMits
6e04989ef8 remove useless file 2025-09-12 20:00:56 +07:00
TcMits
9dac467b40 support EXPLAIN QUERY PLAN 2025-09-12 19:58:45 +07:00
Nikita Sivukhin
ab6c1bd8c7 use arm target for apply builds 2025-09-12 16:50:02 +04:00
Nikita Sivukhin
16b8dff697 fix CI for apple builds 2025-09-12 16:31:02 +04:00
Nikita Sivukhin
4e54f9042c newlines 2025-09-12 16:25:39 +04:00
PThorpe92
5849819a59 Fix tests for views 2025-09-12 08:20:40 -04:00
Nikita Sivukhin
5c922da61a reorder packages in the workspace 2025-09-12 15:57:07 +04:00
Preston Thorpe
b09dcceeef Merge 'Fixes views' from Glauber Costa
This is a collection of fixes for materialized views ahead of adding
support for JOINs.
It is mostly issues with how we assume there is a single table, with a
single delta, but we have to send more than one.
Those are things that are just objectively wrong, so I am sending it
separately to make the JOIN PR smaller.

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

Closes #3009
2025-09-12 07:43:32 -04:00
Nikita Sivukhin
a5fbcb11e5 fix CI 2025-09-12 15:39:38 +04:00
Preston Thorpe
16a3410934 Merge 'Fix checkpoint fast-path, don't use cached pages w/o write lock' from Preston Thorpe
closes #3024
Don't use pages from the cache unless we hold an exclusive write lock,
because a page could be updated by a writer in-memory at any point
before we backfill it.
Clear the WAL tag in other areas to prevent any stale tags. Also, we
will just snapshot the page when we determine that it's eligible, and
pay a memcpy instead of the read from disk, but this further prevents
any in-memory changes to the page/TOCTOU issues, and we also assert that
it's still eligible after we copy it to a new buffer.

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

Closes #3036
2025-09-12 07:39:32 -04:00