Commit Graph

368 Commits

Author SHA1 Message Date
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
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
Jussi Saurio
5583e76981 Fix re-entrancy of op_destroy (used by DROP TABLE)
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
2025-10-07 15:38:30 +03:00
Pekka Enberg
a72b07e949 Merge 'Fix VDBE program abort' from Nikita Sivukhin
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
2025-10-07 09:07:07 +03:00
pedrocarlo
5a7390735d rename Completion functions 2025-10-06 11:07:06 -03:00
Nikita Sivukhin
e2f7310617 add explicit tracker for Txn cleanup necessary for statement 2025-10-06 17:51:43 +04:00
Nikita Sivukhin
afe9a19496 add simple integration test 2025-10-06 13:30:05 +04:00
pedrocarlo
f3dc0bef5d remove some explicit Arc<dyn File> references 2025-10-03 16:39:57 -03:00
pedrocarlo
e93add6c80 remove dyn DatabaseStorage and replace it with DatabaseFile 2025-10-03 14:14:15 -03:00
Pekka Enberg
297aaf4887 core/mvcc: Rename "-lg" to "-log"
The "lg" name is just weird.
2025-10-03 10:08:02 +03:00
Jussi Saurio
d2f5e67b25 Merge 'Fix COLLATE' from Jussi Saurio
Fixes the following problems with COLLATE:
- Fix: incorrectly used e.g. `x COLLATE NOCASE = 'fOo'` as index
constraint on an index whose column was not case-insensitively collated
- Fix: various ephemeral indexes (in GROUP BY, ORDER BY, DISTINCT) and
subqueries did not retain proper collation information of columns
- Fix: collation of a given expression was not determined properly
according to SQLite's rules
Adds TCL tests and fuzz test
Closes #3476
Closes #1524
Closes #3305

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

Closes #3538
2025-10-03 09:34:24 +03:00
Jussi Saurio
b351993cb0 Collate: add fuzz test 2025-10-02 21:49:33 +03:00
Pekka Enberg
3378afe8c6 Merge 'Fix MVCC drop table' from Jussi Saurio
MVCC shuoldn't try to destroy btrees in pager because pager operations
are only done in checkpoint

Closes #3524
2025-10-02 17:26:00 +03:00
Jussi Saurio
bb82f26440 Modify DDL fuzz test to support MVCC too 2025-10-02 14:12:12 +03:00
Jussi Saurio
3a1851ec06 Fix MVCC startup infinite loop when using existing DB
MVCC bootstrap connection got stuck into an infinite statement
reparsing loop because the bootstrap procedure happened before the
on-disk schema was deserialized.
2025-10-02 13:21:44 +03:00
Jussi Saurio
3ff6b44de2 Merge 'Fix index bookkeeping in DROP COLUMN' from Jussi Saurio
Closes #3448. Nasty bug - see issue for details

Closes #3449
2025-10-01 08:57:08 +03:00
Jussi Saurio
8a08f085e8 Merge 'Fix SQLite database file pending byte page' from Pedro Muniz
Sqlite has a crazy easter egg where a 1 Gib file offset, it creates a
`PENDING_BYTE_PAGE` that is used only by the VFS layer, and is never
read or written into.
To properly test this, I took inspiration from SQLITE testing framework,
and defined a helper method, that is conditionally compiled with the
`test_helper` feature enabled.
https://github.com/sqlite/sqlite/blob/7e38287da43ea3b661da3d8c1f431aa907
d648c9/src/main.c#L4327
As the `PENDING_BYTE` is normally at the 1 Gib mark, I created a
function that modifies the static `PENDING_BYTE` atomic to whatever
value we want. This means we can test this unusual behaviours at any DB
file size we want.
`fuzz_pending_byte_database` is the test that fuzzes different pending
byte offsets and does an integrity check at the end to confirm, we are
compatible with SQLITE
Closes #2749
<img width="1100" height="740" alt="image" src="https://github.com/user-
attachments/assets/06eb258f-b4b4-47bf-85f9-df1cf411e1df" />

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

Closes #3431
2025-10-01 08:55:44 +03:00
Jussi Saurio
65abe3efdc Merge 'MVCC: Handle table ID / rootpages properly for both checkpointed and non-checkpointed tables' from Jussi Saurio
**Handle table ID / rootpages properly for both checkpointed and non-
checkpointed tables**
Table ID is an opaque identifier that is only meaningful to the MV
store.
Each checkpointed MVCC table corresponds to a single B-tree on the
pager,
which naturally has a root page.
**We cannot use root page as the MVCC table ID directly because:**
- We assign table IDs during MVCC commit, but
- we commit pages to the pager only during checkpoint
which means the root page is not easily knowable ahead of time.
**Hence:**
- MVCC table ids are always negative
- sqlite_schema rows will have a negative rootpage column if the
  table has not been checkpointed yet.
- on checkpoint when the table is allocated a real root page, we update
the row in sqlite_schema and in MV store's internal mapping
**On recovery:**
- All sqlite_schema tables are read directly from disk and assigned
`table_id = -1 * root_page` -- root_page on disk must be positive
- Logical log is deserialized and inserted into MV store
- Schema changes from logical_log are captured into the DB's global
schema
**Note about recovery:**
I changed MVCC recovery to happen on DB initialization which should
prevent any races, so no need for `recover_lock`, right @pereman2 ?

Closes #3419
2025-10-01 08:55:10 +03:00
Nikita Sivukhin
9ef05adc5e fix upsert conflict handling 2025-09-30 22:39:55 +04:00
pedrocarlo
aa5055e563 fuzz tests for pending_byte 2025-09-30 13:52:40 -03:00
Preston Thorpe
3456d61ac0 Merge 'Index search fixes' from Nikita Sivukhin
This PR bundles 2 fixes:
1. Index search must skip NULL values
2. UPDATE must avoid using index which column is used in the SET clause
    * This was an optimization to not do full scan in case of `UPDATE t
SET ... WHERE col = ?` but instead of doing this hacks we must properly
load updated row set to the ephemeral index and flush it after update
will be finished instead of modifying BTree inplace
    * So, for now we completely remove this optimization and quitely
wait for proper optimization to land

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

Closes #3459
2025-09-30 12:34:52 -04:00
Pekka Enberg
b511b23e70 Merge 'Make encryption opt in via flag' from Avinash Sajjanshetty
We had encryption feature behind a compiler flag. However, it wasn't
enabled by default. This patch:
- enables compiler flag by default
- it also adds an opt in runtime flag `experimental-encryption`
- the runtime flag is disabled by default

Closes #3457
2025-09-30 19:31:28 +03:00
Jussi Saurio
a52dbb7842 Handle table ID / rootpages properly for both checkpointed and non-checkpointed tables
Table ID is an opaque identifier that is only meaningful to the MV store.
Each checkpointed MVCC table corresponds to a single B-tree on the pager,
which naturally has a root page.

We cannot use root page as the MVCC table ID directly because:
- We assign table IDs during MVCC commit, but
- we commit pages to the pager only during checkpoint
which means the root page is not easily knowable ahead of time.

Hence, we:

- store the mapping between table id and btree rootpage
- sqlite_schema rows will have a negative rootpage column if the
  table has not been checkpointed yet.
2025-09-30 16:53:12 +03:00
Jussi Saurio
a1bdad58b6 mvcc: add test to verify that reading both checkpointed and non-checkpointed tables works 2025-09-30 16:53:11 +03:00
Avinash Sajjanshetty
a360efa6e0 enable encryption feature flag by default 2025-09-30 19:04:25 +05:30
Avinash Sajjanshetty
c8111f9555 Put encryption behind an opt in (runtime) flag 2025-09-30 18:29:18 +05:30
Nikita Sivukhin
78c05d8ce3 fix clippy 2025-09-30 16:51:54 +04:00
Nikita Sivukhin
5693d4052c improve fuzz test 2025-09-30 16:47:01 +04:00
Nikita Sivukhin
6d3bdc81e5 add simple test 2025-09-30 16:46:43 +04:00
Nikita Sivukhin
93e7bb5593 add simple test 2025-09-30 16:15:26 +04:00
Nikita Sivukhin
003547d83d fix clippy 2025-09-30 14:44:48 +04:00
Nikita Sivukhin
264cfdd1c0 add smiple test 2025-09-30 13:58:59 +04:00
Jussi Saurio
9681377c51 Merge 'sum() can throw integer overflow' from Duy Dang
close #3311

Closes #3416
2025-09-30 10:38:37 +03:00
Jussi Saurio
38e08253c8 Unignore ALTER TABLE fuzz test
We caught a pretty bad bug quite late because this fuzz test only
ran on btree changes - let's run it on every CI run but with less
iterations than before.
2025-09-30 10:01:18 +03:00
Preston Thorpe
1e974c1383 Merge 'Fix zero limit' from Nikita Sivukhin
Before, we validated that condition during program emit - which works
for fixed values of parameters but doesn't work with variables provided
externally to the prepared statement

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

Closes #3421
2025-09-29 11:06:46 -04:00
Nikita Sivukhin
4d8ef6c63f extend integration test 2025-09-29 15:32:36 +04:00
Duy Dang
8562737d77 sum() can throw integer overflow 2025-09-29 00:27:59 +07:00
Avinash Sajjanshetty
c2453046fa clippy fixes 2025-09-27 18:16:51 +05:30
Avinash Sajjanshetty
a7237b80ea add tests for checking encryption tampering 2025-09-27 17:49:42 +05:30
Jussi Saurio
b43a89e423 Add regression tests for ALTER TABLE stuff 2025-09-27 09:45:15 +03:00
Nikita Sivukhin
5bf69350b3 add simple tests for offset/limit binding 2025-09-26 18:06:20 +04:00
Nikita Sivukhin
a0c47b98b8 fix test 2025-09-26 17:42:11 +04:00
Nikita Sivukhin
52f3216211 fix avg aggregation
- ignore NULL rows as SQLite do
- emit NULL instead of NaN when no rows were aggregated
- adjust agg column alias name
2025-09-26 17:11:06 +04:00
Pere Diaz Bou
91cff65e44 Merge 'Autoincrement' from Pavan Nambi
fixes #1976
and #1605
```zsh
turso> DROP TABLE IF EXISTS t;
CREATE TABLE t (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);
turso> INSERT INTO t (name) VALUES ('A'); SELECT * FROM sqlite_sequence;
┌──────┬─────┐
│ name │ seq │
├──────┼─────┤
│ t    │   1 │
└──────┴─────┘
turso> DROP TABLE IF EXISTS t;
CREATE TABLE t (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);
turso> INSERT INTO t (name) VALUES ('A'); SELECT * FROM sqlite_sequence;
┌──────┬─────┐
│ name │ seq │
├──────┼─────┤
│ t    │   1 │
└──────┴─────┘
turso> INSERT INTO t (name) VALUES ('A'); SELECT * FROM sqlite_sequence;
┌──────┬─────┐
│ name │ seq │
├──────┼─────┤
│ t    │   2 │
└──────┴─────┘
turso>
```

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

Closes #2983
2025-09-25 18:57:24 +02: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
b12387b2e3 mvcc/fuzz: make some ALTER TABLE ops in mvcc fuzz test 2025-09-25 11:49:18 +03:00
Jussi Saurio
f7806cbc33 mvcc: add basic checkpoint test 2025-09-25 08:12:13 +03:00
Pavan-Nambi
49d5141f2d Merge remote-tracking branch 'origin/main' into cdc_fail_autoincrement 2025-09-24 18:06:02 +05:30