Commit Graph

8003 Commits

Author SHA1 Message Date
themixednuts
80eca66be9 fix: normalize quotes in update
fixes: #2744
2025-08-23 03:17:03 -05:00
Pekka Enberg
52f66e6c60 Merge 'Add syntax highlighting for EXPLAIN and ANALYZE' from Alex Miller
I'm working on ANALYZE.  I'm using EXPLAIN.  The lack of highlighting
for them in the CLI annoyed me a bit.
I don't think there's any tests for this?  I'm mostly at a "it seems to
work for me".  I double checked that `EXPLAIN SELECT CASE 0 WHEN 0 THEN
0 ELSE 1` syntax highlights, to make sure  I didn't break the longer
parsing (which I had).

Closes #2741
2025-08-23 10:51:31 +03:00
Pekka Enberg
dd56eb7d9b Merge 'Add basic support for ANALYZE statement' from Alex Miller
This is part 1 of N implementing #656
This permits only `ANALYZE <table_name>` to work, and all other forms
fail with a parse error (as documented in the tests).
On SQLite, ANALYZE generates:
```
sqlite> CREATE TABLE sqlite_stat1(tbl,idx,stat);
sqlite> CREATE TABLE iiftest(a int, b int, c int); sqlite> EXPLAIN ANALYZE iiftest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     21    0                    0   Start at 21
1     Null           0     1     0                    0   r[1]=NULL
2     OpenWrite      3     4     0     3              0   root=4 iDb=0; sqlite_stat1
3     Rewind         3     9     0                    0
4       Column         3     0     2                    0   r[2]= cursor 3 column 0
5       Ne             3     8     2     BINARY-8       81  if r[2]!=r[3] goto 8
6       Rowid          3     4     0                    0   r[4]=sqlite_stat1.rowid
7       Delete         3     0     0     sqlite_stat1   2
8     Next           3     4     0                    1
9     OpenWrite      0     4     0     3              0   root=4 iDb=0; sqlite_stat1
10    OpenRead       4     2     0     3              0   root=2 iDb=0; iiftest
11    String8        0     11    0     iiftest        0   r[11]='iiftest'; iiftest
12    Count          4     13    0                    0   r[13]=count()
13    IfNot          13    18    0                    0
14    Null           0     12    0                    0   r[12]=NULL
15    MakeRecord     11    3     9     BBB            0   r[9]=mkrec(r[11..13])
16    NewRowid       0     5     0                    0   r[5]=rowid
17    Insert         0     9     5                    8   intkey=r[5] data=r[9]
18    LoadAnalysis   0     0     0                    0
19    Expire         0     0     0                    0
20    Halt           0     0     0                    0
21    Transaction    0     1     9     0              1   usesStmtJournal=0
22    String8        0     3     0     iiftest        0   r[3]='iiftest'
23    Goto           0     1     0                    0
```
Turso can now generate:
```
turso> create table sqlite_stat1(tbl,idx,stat);
turso> create table iiftest(a int, b int, c int);
turso> explain analyze iiftest;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     19    0                    0   Start at 19
1     Null               0     1     0                    0   r[1]=NULL
2     OpenWrite          0     2     0                    0   root=2; iDb=0
3     Rewind             0     9     0                    0   Rewind  sqlite_stat1
4       Column           0     0     2                    0   r[2]=sqlite_stat1.tbl
5       Ne               2     3     9                    0   if r[2]!=r[3] goto 9
6       RowId            0     4     0                    0   r[4]=sqlite_stat1.rowid
7       Delete           0     0     0     sqlite_stat1   0
8     Next               0     4     0                    0
9     OpenWrite          1     2     0                    0   root=2; iDb=0
10    OpenRead           2     3     0                    0   =iiftest, root=3, iDb=0
11    String8            0     7     0     iiftest        0   r[7]='iiftest'
12    Count              2     9     0                    0
13    IfNot              9     18    0                    0   if !r[9] goto 18
14    Null               0     8     0                    0   r[8]=NULL
15    MakeRecord         7     3     6                    0   r[6]=mkrec(r[7..9])
16    NewRowid           1     5     0                    0   r[5]=rowid
17    Insert             1     6     5     sqlite_stat1   0   intkey=r[5] data=r[6]
18    Halt               0     0     0                    0
19    String8            0     3     0     iiftest        0   r[3]='iiftest'
20    Goto               0     1     0                    0
```
Note the missing support for LoadAnalysis and Expire, but there's no
optimizer work done yet to leverage any gathered statistics yet anyway.

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

Closes #2740
2025-08-23 10:50:57 +03:00
Alex Miller
4619890ffc Add basic support for ANALYZE statement.
This permits only `ANALYZE <table_name>` to work, and all other forms
fail with a parse error (as documented in the tests).

On SQLite, ANALYZE generates:

sqlite> CREATE TABLE sqlite_stat1(tbl,idx,stat);
sqlite> CREATE TABLE iiftest(a int, b int, c int);
sqlite> EXPLAIN ANALYZE iiftest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     21    0                    0   Start at 21
1     Null           0     1     0                    0   r[1]=NULL
2     OpenWrite      3     4     0     3              0   root=4 iDb=0; sqlite_stat1
3     Rewind         3     9     0                    0
4       Column         3     0     2                    0   r[2]= cursor 3 column 0
5       Ne             3     8     2     BINARY-8       81  if r[2]!=r[3] goto 8
6       Rowid          3     4     0                    0   r[4]=sqlite_stat1.rowid
7       Delete         3     0     0     sqlite_stat1   2
8     Next           3     4     0                    1
9     OpenWrite      0     4     0     3              0   root=4 iDb=0; sqlite_stat1
10    OpenRead       4     2     0     3              0   root=2 iDb=0; iiftest
11    String8        0     11    0     iiftest        0   r[11]='iiftest'; iiftest
12    Count          4     13    0                    0   r[13]=count()
13    IfNot          13    18    0                    0
14    Null           0     12    0                    0   r[12]=NULL
15    MakeRecord     11    3     9     BBB            0   r[9]=mkrec(r[11..13])
16    NewRowid       0     5     0                    0   r[5]=rowid
17    Insert         0     9     5                    8   intkey=r[5] data=r[9]
18    LoadAnalysis   0     0     0                    0
19    Expire         0     0     0                    0
20    Halt           0     0     0                    0
21    Transaction    0     1     9     0              1   usesStmtJournal=0
22    String8        0     3     0     iiftest        0   r[3]='iiftest'
23    Goto           0     1     0                    0

Turso can now generate:

turso> create table sqlite_stat1(tbl,idx,stat);
turso> create table iiftest(a int, b int, c int);
turso> explain analyze iiftest;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     19    0                    0   Start at 19
1     Null               0     1     0                    0   r[1]=NULL
2     OpenWrite          0     2     0                    0   root=2; iDb=0
3     Rewind             0     9     0                    0   Rewind  sqlite_stat1
4       Column           0     0     2                    0   r[2]=sqlite_stat1.tbl
5       Ne               2     3     9                    0   if r[2]!=r[3] goto 9
6       RowId            0     4     0                    0   r[4]=sqlite_stat1.rowid
7       Delete           0     0     0     sqlite_stat1   0
8     Next               0     4     0                    0
9     OpenWrite          1     2     0                    0   root=2; iDb=0
10    OpenRead           2     3     0                    0   =iiftest, root=3, iDb=0
11    String8            0     7     0     iiftest        0   r[7]='iiftest'
12    Count              2     9     0                    0
13    IfNot              9     18    0                    0   if !r[9] goto 18
14    Null               0     8     0                    0   r[8]=NULL
15    MakeRecord         7     3     6                    0   r[6]=mkrec(r[7..9])
16    NewRowid           1     5     0                    0   r[5]=rowid
17    Insert             1     6     5     sqlite_stat1   0   intkey=r[5] data=r[6]
18    Halt               0     0     0                    0
19    String8            0     3     0     iiftest        0   r[3]='iiftest'
20    Goto               0     1     0                    0

Note the missing support for LoadAnalysis and Expire, but there's no
optimizer work done yet to leverage any gathered statistics yet anyway.
2025-08-22 23:18:53 -07:00
Alex Miller
327936fb51 Highlight the EXPLAIN keyword 2025-08-22 22:49:58 -07:00
Alex Miller
f1250a6c86 Add syntax highlighting for ANALYZE 2025-08-22 22:47:46 -07:00
Pekka Enberg
78295e3b4c Merge 'wal-api: allow to mix frames insert with SQL execution' from Nikita Sivukhin
This PR make it possible to do 2 pretty crazy things with turso-db:
1. Now we can mix WAL frames inserts with SQL execution within same
transaction. This will allow sync engine to execute rebase of local
changes within atomically over main database file (the operation first
require us to push new frames to physically revert local changes and
then we need to replay local logical changes on top of the modified DB
state)
2. Under `conn_raw_api` Cargo feature turso-db now expose method which
allow caller to specify WAL file path. This dangerous capability exposed
for sync-engine which maintain 2 databases: main one and "revert"-DB
which shares same DB file but has it's own separate WAL. As sync-engine
has full control over checkpoint - it can guarantee that DB file will be
consistent with both main and "revert" DB WALs.

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

Closes #2716
2025-08-22 15:41:43 +03:00
Pekka Enberg
92bf7b3daa Merge 'Fix blob type handling in JavaScript' from Pekka Enberg
Closes #2732
2025-08-22 15:40:24 +03:00
Pekka Enberg
52ef4c2dfe Merge 'correctly implement offset() in parser' from Lâm Hoàng Phúc
Closes #2731
2025-08-22 15:40:18 +03:00
Pekka Enberg
5ac9195e93 Merge 'move check code into parser' from Lâm Hoàng Phúc
Closes #2730
2025-08-22 15:40:00 +03:00
Pekka Enberg
ce6b824837 Merge 'Serialize compat tests and use Mutex::lock() instead of Mutex::try_lock() in UnixIO' from Jussi Saurio
Closes #2715
1. Since our multithreading isn't proven correct (and is actually
probably all kinds of incorrect), let's serialize these tests since they
operate on the same database
2. Use `lock()` instead of `try_lock()` - i.e. wait to obtain the lock
on the file instead of immediately erroring if we can't

Closes #2729
2025-08-22 15:39:26 +03:00
Pekka Enberg
a259d123de testing/javascript: Add test case for blobs 2025-08-22 14:17:45 +03:00
Pekka Enberg
9aff35e5af packages/turso-serverless: Fix blob type handling 2025-08-22 14:17:40 +03:00
Pekka Enberg
2c68613709 bindings/javascript: Fix blob type handling 2025-08-22 14:17:40 +03:00
TcMits
81603f6706 correctly implement offset() in parser 2025-08-22 17:47:39 +07:00
TcMits
4b07555e87 remove dup test 2025-08-22 17:02:10 +07:00
TcMits
f49c47f248 remove dup check 2025-08-22 16:47:41 +07:00
TcMits
df8ab9c104 clippy again 2025-08-22 16:39:59 +07:00
TcMits
a1bc3bf988 clippy 2025-08-22 16:36:10 +07:00
TcMits
14eb8a8ffe move check code into parser 2025-08-22 16:28:56 +07:00
Jussi Saurio
14873c76fb unixio: use Mutex::lock() instead of Mutex::try_lock()
we should wait to obtain the lock, not immediately fail if we cant.
2025-08-22 10:47:50 +03:00
Jussi Saurio
6c7abc5caa Serialize compat tests to prevent file locking failures 2025-08-22 10:38:47 +03:00
Jussi Saurio
cf64452139 Merge 'sim: remove "run_once faults"' from Jussi Saurio
This kind of fault does not semantically represent anything real, since
we already have fault injection for every concrete IO operation like
reading, writing, syncing and so forth.
Moreover, having this feature is the direct cause of the false positive
simulator failure as reported in issue #2727. There, a "run_once fault"
happened immediately after we fsynced following an INSERT, which caused
the simulator to think the INSERT failed, and later a sim assertion
failed because the on-disk database had 1 more row than it thought it
would.
Closes #2727

Reviewed-by: Pekka Enberg <penberg@iki.fi>

Closes #2728
2025-08-22 10:30:36 +03:00
Jussi Saurio
cc643362a4 sim: remove "run_once faults"
This kind of fault does not semantically represent anything real,
since we already have fault injection for every concrete IO operation
like reading, writing, syncing and so forth.

Moreover, having this feature is the direct cause of the false positive
simulator failure as reported in issue #2727. There, a "run_once fault"
happened immediately after we fsynced following an INSERT, which caused
the simulator to think the INSERT failed, and later a sim assertion failed
because the on-disk database had 1 more row than it thought it would.
2025-08-22 10:13:06 +03:00
Pekka Enberg
b9bb859271 Merge 'Switch to new parser in core' from Levy A.
Integrate #2381 to core. Resolves #2337.

Reviewed-by: Lâm Hoàng Phúc (@TcMits)

Closes #2650
2025-08-22 10:06:37 +03:00
Levy A.
34724a0571 fix: proper parser offset tracking 2025-08-22 02:11:53 -03:00
Pekka Enberg
156352fabc Merge ' should not return a Completion when there is a page cache hit' from Pedro Muniz
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2723
2025-08-22 07:33:28 +03:00
Pekka Enberg
b4b156cca9 Merge 'github: Remove Intel Mac support' from Pekka Enberg
They're very close to end of life and we're having macOS runner
availability problems.

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

Closes #2726
2025-08-22 07:33:18 +03:00
Pekka Enberg
3547bd1093 github: Remove Intel Mac support
They're very close to end of life and we're having macOS runner
availability problems.
2025-08-21 23:59:15 +03:00
Pekka Enberg
f1bde3c12c Merge 'github: Reduce Python build matrix' from Pekka Enberg
Test with the earliest and latest supported versions, but skip the ones
in the middle to reduce our Python CI build matrix.

Closes #2724
2025-08-21 23:50:19 +03:00
Jussi Saurio
4edbf3aac0 Merge 'Page cache truncate' from Nikita Sivukhin
Add `truncate` method in the page cache which remove all entries which
reference pages greater than new DB size.
This will be used in the sync engine as in its case DB size can shrink
when we "rebase" changes from remote to local.
It stands on the #2707 because touch few files from that PR

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

Closes #2711
2025-08-21 23:34:39 +03:00
Levy A.
ee12ef9fb5 remove unnecessary Box<ast::Select> 2025-08-21 17:20:25 -03:00
Pekka Enberg
b5dafe2f07 github: Reduce Python build matrix
Test with the earliest and latest supported versions, but skip the ones
in the middle to reduce our Python CI build matrix.
2025-08-21 22:50:51 +03:00
Levy A.
8a610a776f refactor: Result type alias 2025-08-21 15:24:01 -03:00
Levy A.
07975603d3 fix: incorrect sql statement in parser test 2025-08-21 15:24:01 -03:00
Levy A.
d9c7cbf7f2 fix: report TK_ILLEGAL as error 2025-08-21 15:24:01 -03:00
Levy A.
0138aade31 tidy error reporting 2025-08-21 15:24:01 -03:00
Levy A.
8f198a3086 fix create view columns length check 2025-08-21 15:24:01 -03:00
Levy A.
a86a066a91 fix order by function clause 2025-08-21 15:24:01 -03:00
Levy A.
4ba1304fb9 complete parser integration 2025-08-21 15:23:59 -03:00
Levy A.
c6b032de63 feat: add AST formating and checking 2025-08-21 15:19:17 -03:00
Levy A.
f8daf2ff95 fix: copy TokenType's as_str from the old parser 2025-08-21 15:19:17 -03:00
Levy A.
b0537d02c7 fix: SQLite operators are left associative 2025-08-21 15:19:16 -03:00
Levy A.
40fce89238 fix: empty variables are allowed 2025-08-21 15:19:16 -03:00
Levy A.
8f10f2f240 fix number parser
the added test case was failing
2025-08-21 15:19:16 -03:00
Levy A.
dd39f47cda feat: add materialized view + implement essential methods for core 2025-08-21 15:19:16 -03:00
Levy A.
186e2f5d8e switch to new parser 2025-08-21 15:19:16 -03:00
pedrocarlo
6b0ed08465 read_page should return No Completion when have a page cache hit 2025-08-21 14:39:24 -03:00
Pekka Enberg
ae8b1eb00d Merge 'core/io: Don't open file as non-blocking in Unix backend' from Pekka Enberg
The Unix backend is a syscall()-based, blocking implementation. The
O_NONBLOCK adds nothing.

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

Closes #2708
2025-08-21 19:13:39 +03:00
Nikita Sivukhin
fdb80746be fix clippy 2025-08-21 18:28:16 +04:00