Commit Graph

553 Commits

Author SHA1 Message Date
Jussi Saurio
359cba0474 Use BufferPool owned by Database instead of a static global
Problem

There are several problems with our current statically allocated
`BufferPool`.

1. You cannot open two databases in the same process with different
page sizes, because the `BufferPool`'s `Arena`s will be locked forever
into the page size of the first database. This is the case regardless
of whether the two `Database`s are open at the same time, or if the first
is closed before the second is opened.

2. It is impossible to even write Rust tests for different page sizes because
of this, assuming the test uses a single process.

Solution

Make `Database` own `BufferPool` instead of it being statically allocated, so this
problem goes away.

Note that I didn't touch the still statically-allocated `TEMP_BUFFER_CACHE`, because
it should continue to work regardless of this change. It should only be a problem if
the user has two or more databases with different page sizes open simultaneously, because
`TEMP_BUFFER_CACHE` will only support one pool of a given page size at a time, so the rest
of the allocations will go through the global allocator instead.

Notes

I extracted this change out from #2569, because I didn't want it to be smuggled in without
being reviewed as an individual piece.
2025-08-14 10:29:52 +03:00
Glauber Costa
337f27a433 rename some structures to mention materialized views
A lot of the structures we have - like the ones under Schema, are
specific for materialized views. In preparation to adding normal views,
rename them, so things are less confusing.
2025-08-13 14:13:16 -05:00
Nikita Sivukhin
56b86cd5f5 add comment about :memory: in sync-engine 2025-08-13 17:16:46 +04:00
Nikita Sivukhin
80476b3069 bypass database registry for all dbs which path starts with :memory: prefix
- sync engine create pair of databases and they must be isolated but live in the same MemoryIO
- the problem can happen if there will be 2 sync engines with MemoryIO storage layer - as they all will create :memory:-draft and :memory:-synced DBs
2025-08-13 17:00:01 +04:00
Nikita Sivukhin
615207fb9c use proper event loop in core connection in order to handle all cases properly
- otherwise, in case of schema change, connection will constantly get Database schema is changed error as reprepare logic is implemented in the statement event loop
2025-08-13 17:00:01 +04:00
Nikita Sivukhin
5838efe7dd rename flag to wal_auto_checkpoint_disabled 2025-08-13 15:26:25 +04:00
Nikita Sivukhin
f9f56f454c change semantic of wal_disable_checkpoint flag - it disable only automatic checkpoint (on shutdown or when WAL is grows too big) 2025-08-13 15:23:18 +04:00
pedrocarlo
8d48be0e61 cleanup 2025-08-13 10:24:55 +03:00
pedrocarlo
fbe7e685ce adjust mvcc code to return completions in state machines 2025-08-13 10:24:55 +03:00
pedrocarlo
b6e200dbed adjust cacheflush calls outside of pager 2025-08-13 10:24:55 +03:00
pedrocarlo
85e86d427b cleanups - use io.block in many functions and return_if_io 2025-08-13 08:32:38 +03:00
pedrocarlo
217c9061e8 advance commit_tx state machine in mvcc tests 2025-08-12 12:28:35 -03:00
pedrocarlo
78a89f0fd3 execute should create an Statement 2025-08-12 12:28:35 -03:00
Nikita Sivukhin
d66d6d0220 add few comments 2025-08-12 18:41:30 +04:00
Nikita Sivukhin
1d8ed9aa55 add methods for read/write schema cookie 2025-08-12 17:29:56 +04:00
Jussi Saurio
9b5e61eacd Merge 'Reprepare fix on write statement' from Pedro Muniz
We have to update the Transaction State before checking for the Schema
Cookie so that we can rollback the transaction later on correctly.
Closes #2535

Closes #2549
2025-08-12 10:18:12 +03:00
Pekka Enberg
2fa501158c Merge 'turso-cdc: add updates column for cdc table' from Nikita Sivukhin
This PR adds new `updates` column to the CDC table. This column holds
updated fields of the row in the following format:
```
[C boolean values where true set for changed columns]
[C values with updates where NULL is set for not-changed columns]
```
For example:
```
turso> UPDATE t SET y = 'turso', q = 'db' WHERE rowid = 1;
turso> SELECT bin_record_json_object('["x","y","z","q","x","y","z","q"]', updates) as updates FROM turso_cdc;
┌──────────────────────────────────────────────────────────────────┐
│ updates                                                          │
├──────────────────────────────────────────────────────────────────┤
│ {"x":0,"y":1,"z":0,"q":1,"x":null,"y":"turso","z":null,"q":"db"} │
└──────────────────────────────────────────────────────────────────┘
```
Also, this column works differently for `ALTER TABLE` statements where
update value for `sql` will be equal to the original `ALTER TABLE`:
```
turso> ALTER TABLE t ADD COLUMN t;
turso> SELECT bin_record_json_object('["type","name","tbl_name","rootpage","sql","type","name","tbl_name","rootpage","sql"]', updates) as updates FROM turso_cdc WHERE rowid = 2;
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ updates                                                                                                                                           │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ {"type":0,"name":0,"tbl_name":0,"rootpage":0,"sql":1,"type":null,"name":null,"tbl_name":null,"rootpage":null,"sql":"ALTER TABLE t ADD COLUMN t;"} │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```
This will help turso-db to implement logical replication which supports
both column-level updates and schema changes

Closes #2538
2025-08-12 09:50:16 +03:00
pedrocarlo
96a6bc5125 end_tx does not need schema_did_change variable 2025-08-11 18:59:11 -03:00
PThorpe92
4dbf69545e try_borrow.unwrap -> borrow 2025-08-11 13:54:00 -04:00
Lucas Forato
e07ab423e6 feat: removed module_name from VirtualTable, instead looking only at symbol tables 2025-08-11 11:43:32 -03:00
Lucas Forato
9fe20a178a fix: formatting 2025-08-11 09:01:27 -03:00
Lucas Forato
76838bb46a fix: issues from rebase 2025-08-11 08:54:42 -03:00
Lucas Forato
562076fdb8 fix: close method 2025-08-11 08:42:19 -03:00
Lucas Forato
19c445f8b1 feat: listing both used and non-used modules 2025-08-11 08:42:08 -03:00
Lucas Forato
adb69f21f9 feat: remove mods 2025-08-11 08:42:08 -03:00
Lucas Forato
8b1b79bc93 fix: broken file after merge 2025-08-11 08:42:08 -03:00
Lucas Forato
4161f68774 Update core/lib.rs
Co-authored-by: bit-aloo <84662239+Shourya742@users.noreply.github.com>
2025-08-11 08:42:03 -03:00
Lucas Forato
5aa99f6743 feat: listing all modules 2025-08-11 08:42:03 -03:00
Nikita Sivukhin
5d0ada9fb9 add "updates" column for cdc table 2025-08-11 12:46:15 +04:00
Pekka Enberg
6e8d1a5c7d Merge 'Initial pass on incremental view maintenance with DBSP' from Glauber Costa
Implement very basic views using DBSP
This is just the bare minimum that I needed to convince myself that this
 approach will work. The only views that we support are slices of the
 main table: no aggregations, no joins, no projections.
 * drop view is implemented.
 * view population is implemented.
 * deletes, inserts and updates are implemented.
 much like indexes before, a flag must be passed to enable views.

Closes #2530
2025-08-11 07:45:43 +03:00
Glauber Costa
145d6eede7 Implement very basic views using DBSP
This is just the bare minimum that I needed to convince myself that this
approach will work. The only views that we support are slices of the
main table: no aggregations, no joins, no projections.

drop view is implemented.
view population is implemented.
deletes, inserts and updates are implemented.

much like indexes before, a flag must be passed to enable views.
2025-08-10 23:34:04 -05:00
Glauber Costa
d5b7533ff8 Implement a DBSP module
We are not using the DBSP crate because it is very heavy on Tokio and
other dependencies that won't make sense for us to consume.
2025-08-10 23:15:26 -05:00
PThorpe92
213d589dd1 Apply review suggestions, remove FreeEntry 2025-08-08 11:07:29 -04:00
PThorpe92
9d1ca1c8ca Add ReadFixed/WriteFixed opcodes for buffers from registered arena 2025-08-08 10:55:27 -04:00
PThorpe92
7ea52a3f89 Fix changing page size and initialization for buffer pool 2025-08-08 10:55:26 -04:00
PThorpe92
5750b1229c Setup and initialize pool properly 2025-08-08 10:55:26 -04:00
Preston Thorpe
d3e6172516 Merge 'global allocator should not be set for library, only for executables' from Pedro Muniz
We should be allocator-agnostic. It is pretty limiting for us to force a
user to use a particular allocator. This is specially restricting for
`no_std` in the future.

Reviewed-by: bit-aloo (@Shourya742)
Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #2481
2025-08-08 09:45:35 -04:00
Pekka Enberg
0f9d0cf519 Merge branch 'main' into 2025-08-07-add-query-only-pragma 2025-08-08 07:41:38 +03:00
PThorpe92
98f4e5cd2d Add comment/TODO about method we use to copy the db file 2025-08-07 16:27:08 -04:00
PThorpe92
e32d04ea97 Use ephemeral PlatformIO for clone method to support memory io 2025-08-07 16:27:08 -04:00
PThorpe92
039fe22405 Add copy_to to io::File trait to support copying DB files 2025-08-07 16:27:02 -04:00
bit-aloo
ef084af42f Add getter and setter methods 2025-08-07 23:44:54 +05:30
bit-aloo
697eb35ca9 Add query_only field to Connection 2025-08-07 23:44:29 +05:30
pedrocarlo
edae65fb5f global allocator should not be set for library, only for executables 2025-08-07 13:41:50 -03:00
PThorpe92
f6a68cffc2 Remove RefCell from IO and Page apis 2025-08-05 16:24:49 -04:00
Jussi Saurio
3f633247f7 perf/stmt: avoid checking for SchemaUpdated errors if it's impossible 2025-08-05 15:10:55 +03:00
Jussi Saurio
a66b56678d Merge 'Reprepare Statements when Schema changes' from Pedro Muniz
Closes #1967
To support this I had to change how we did `epilogue` similarly to how
SQLite does it. SQLIte first declares a `beginWriteOperation` when some
statement is going to necessitate a Write Transaction. And as we now
need to pass the current schema cookie to `epilogue` it was easier to
call epilogue only in one location (like we do with prologue), and just
have each statement declare their intentions separately. This allows us
to not have to pass the Schema around just to do the epilogue. I believe
this is something that @jussisaurio would be interested in.
~Also had to disable the MVCC test, as it was extremely buggy for me.~
Just disabled reprepare statements for MVCC

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

Closes #2214
2025-08-05 00:01:14 +03:00
Nikita Sivukhin
443c177d13 fix test for windows 2025-08-04 21:00:29 +04:00
pedrocarlo
0e3e64878c workaround the fact that to reparse schema we have to avoid falling into a reprepared statement loop 2025-08-04 12:32:34 -03:00
pedrocarlo
266a7e1c66 do not error in op_transaction if page 1 was not allocated 2025-08-04 12:32:34 -03:00