pedrocarlo
5bd47d7462
post rebase adjustments to accomodate new instructions that were created before the merge conflicts
2025-05-19 15:22:15 -03:00
pedrocarlo
bf1fe9e0b3
Actually fixed group by and order by collation
2025-05-19 15:22:15 -03:00
pedrocarlo
0df6c87f07
Fixed Group By collation
2025-05-19 15:22:14 -03:00
pedrocarlo
d0a63429a6
Naive implementation of collate for queries. Not implemented for column constraints
2025-05-19 15:22:14 -03:00
pedrocarlo
b5b1010e7c
set binary collation as default
2025-05-19 15:22:14 -03:00
Jussi Saurio
8d66347729
vdbe: add Insn::Found
2025-05-17 15:33:55 +03:00
pedrocarlo
5f2216cf8e
modify explain for MakeRecord to show index name
2025-05-14 13:30:39 -03:00
pedrocarlo
5bae32fe3f
modified OpenWrite to include index or table name in explain
2025-05-14 13:30:39 -03:00
pedrocarlo
e7fa023c26
Adding indexes to the update plan
2025-05-14 13:30:39 -03:00
pedrocarlo
b69debb8c0
create count opcode
2025-05-10 22:23:01 -03:00
Pekka Enberg
14ef25ebb8
Merge 'Add drop index' from Anton Harniakou
...
This commit adds suport for DROP INDEX.
Bytecode produced by this commit differs from SQLITE's bytecode, main
reason we don't do autovacuum or repacking of pages like SQLITE does.
Closes #1280
Closes #1444
2025-05-10 08:04:39 +03:00
Pekka Enberg
be1621e099
Merge 'EXPLAIN should show a comment for the Insert opcode' from Anton Harniakou
...
After this commit EXPLAIN should show a comment for `Insert`.
```
limbo> explain insert into t (age, name, id) values (20, 'max', 1);
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 9 0 0 Start at 9
1 OpenWrite 0 2 0 0
2 Integer 1 2 0 0 r[2]=1
3 String8 0 3 0 max 0 r[3]='max'
4 Integer 20 4 0 0 r[4]=20
5 NewRowId 0 1 0 0
6 MakeRecord 2 3 5 0 r[5]=mkrec(r[2..4])
7 Insert 0 5 1 t 0 intkey=r[1] data=r[5]
8 Halt 0 0 0 0
9 Transaction 0 1 0 0 write=true
10 Goto 0 1 0 0
```
Closes #1452
2025-05-10 07:59:36 +03:00
Levy A.
023a116b0d
feat: initial implementation of ALTER TABLE
...
only supporting renaming tables
2025-05-08 09:24:56 -03:00
Anton Harniakou
d74df2473e
EXPLAIN should show a comment for the Insert opcode
2025-05-05 10:54:59 +03:00
Anton Harniakou
6c8eef2fac
Support DROP INDEX
...
This commit adds suport for DROP INDEX.
Bytecode produced by this commit differs from SQLITE's bytecode, main
reason we don't do autovacuum or repacking of pages like SQLITE does.
2025-05-04 12:13:16 +03:00
Jussi Saurio
306e097950
Merge 'Fix bug: we cant remove order by terms from the head of the list' from Jussi Saurio
...
we had an incorrect optimization in `eliminate_orderby_like_groupby()`
where it could remove e.g. the first term of the ORDER BY if it matched
the first GROUP BY term and the result set was naturally ordered by that
term. this is invalid. see e.g.:
```sql
main branch - BAD: removes the `ORDER BY id` term because the results are naturally ordered by id.
However, this results in sorting the entire thing by last name only!
limbo> select id, last_name, count(1) from users GROUP BY 1,2 order by id, last_name desc limit 3;
┌──────┬───────────┬───────────┐
│ id │ last_name │ count (1) │
├──────┼───────────┼───────────┤
│ 6235 │ Zuniga │ 1 │
├──────┼───────────┼───────────┤
│ 8043 │ Zuniga │ 1 │
├──────┼───────────┼───────────┤
│ 944 │ Zimmerman │ 1 │
└──────┴───────────┴───────────┘
after fix - GOOD:
limbo> select id, last_name, count(1) from users GROUP BY 1,2 order by id, last_name desc limit 3;
┌────┬───────────┬───────────┐
│ id │ last_name │ count (1) │
├────┼───────────┼───────────┤
│ 1 │ Foster │ 1 │
├────┼───────────┼───────────┤
│ 2 │ Salazar │ 1 │
├────┼───────────┼───────────┤
│ 3 │ Perry │ 1 │
└────┴───────────┴───────────┘
I also refactored sorters to always use the ast `SortOrder` instead of boolean vectors, and use the `compare_immutable()` utility we use inside btrees too.
Closes #1365
2025-05-03 12:48:08 +03:00
Pere Diaz Bou
63a94e7c62
Merge 'Emit IdxDelete instruction and some fixes on seek after deletion' from Pere Diaz Bou
...
Previously `DELETE FROM ...` only emitted deletes for main table, but
this is incorrect as we want to remove entries from index tables as
well.
Closes #1383
2025-04-28 09:13:54 +03:00
pedrocarlo
2e147b20a8
Adjustments and explicitely just emitting NoConflict on unique indexes
2025-04-24 13:13:39 -03:00
Pere Diaz Bou
b7970a286d
implement IdxDelete
...
clippy
revert op_idx_ge changes
fmt
fmt again
rever op_idx_gt changes
2025-04-24 16:23:34 +02:00
Jussi Saurio
3798b4aa8b
use SortOrder in sorters always
2025-04-24 10:34:06 +03:00
pedrocarlo
b6036cc79d
Primary key constraint working
2025-04-23 16:44:13 -03:00
PThorpe92
853af16946
Implement xBestIndex for virtual table api to improve query planning
2025-04-17 13:53:27 -04:00
Jussi Saurio
13a703d636
Merge 'Add BeginSubrtn, NotFound and Affinity bytecodes' from Diego Reis
...
I'm working on an optimization of `WHERE .. IN (..)` statements that
requires these bytecodes.
```sh
sqlite> explain select * from users where first_name in ('alice', 'bob', 'charlie');
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 35 0 0 Start at 35
1 OpenRead 0 2 0 10 0 root=2 iDb=0; users
2 Rewind 0 34 0 0
3 Noop 0 0 0 0 begin IN expr
4 BeginSubrtn 0 1 0 0 r[1]=NULL <---- Here
5 Once 0 17 0 0
6 OpenEphemeral 1 1 0 k(1,B) 0 nColumn=1; RHS of IN operator
7 String8 0 2 0 alice 0 r[2]='alice'
8 MakeRecord 2 1 3 B 0 r[3]=mkrec(r[2])
9 IdxInsert 1 3 2 1 0 key=r[3]
10 String8 0 2 0 bob 0 r[2]='bob'
11 MakeRecord 2 1 3 B 0 r[3]=mkrec(r[2])
12 IdxInsert 1 3 2 1 0 key=r[3]
13 String8 0 2 0 charlie 0 r[2]='charlie'
14 MakeRecord 2 1 3 B 0 r[3]=mkrec(r[2])
15 IdxInsert 1 3 2 1 0 key=r[3]
16 NullRow 1 0 0 0
17 Return 1 5 1 0
18 Column 0 1 4 0 r[4]= cursor 0 column 1
19 IsNull 4 33 0 0 if r[4]==NULL goto 33
20 Affinity 4 1 0 B 0 affinity(r[4]) <---- Here
21 NotFound 1 33 4 1 0 key=r[4]; end IN expr <---- Here
22 Rowid 0 5 0 0 r[5]=users.rowid
23 Column 0 1 6 0 r[6]= cursor 0 column 1
24 Column 0 2 7 0 r[7]= cursor 0 column 2
25 Column 0 3 8 0 r[8]= cursor 0 column 3
26 Column 0 4 9 0 r[9]= cursor 0 column 4
27 Column 0 5 10 0 r[10]= cursor 0 column 5
28 Column 0 6 11 0 r[11]= cursor 0 column 6
29 Column 0 7 12 0 r[12]= cursor 0 column 7
30 Column 0 8 13 0 r[13]= cursor 0 column 8
31 Column 0 9 14 0 r[14]= cursor 0 column 9
32 ResultRow 5 10 0 0 output=r[5..14]
33 Next 0 3 0 1
34 Halt 0 0 0 0
35 Transaction 0 0 3 0 1 usesStmtJournal=0
36 Goto 0 1 0 0
```
EDIT: [Found](https://sqlite.org/opcode.html#Found ) and
[NoConflict](https://sqlite.org/opcode.html#NoConflict ) can be easily
derived from `NotFound` but I wanted to be concise, I could do it in
another PR :)
Closes #1345
2025-04-15 20:25:55 +03:00
Diego Reis
2cc492844e
Improve NotFound's docs clarity
2025-04-15 13:36:45 -03:00
Diego Reis
58efb90467
core: Add Affinity bytecode
...
Apply affinities to a range of P2 registers starting with P1.
P4 is a string that is P2 characters long. The N-th character of the string indicates the column affinity that should be used for the N-th memory cell in the range.
2025-04-15 09:52:04 -03:00
Diego Reis
c5161311fc
core/vdbe: Add NotFound bytecode
...
If P4==0 then register P3 holds a blob constructed by MakeRecord. If P4>0 then register P3 is the first of P4 registers that form an unpacked record.
Cursor P1 is on an index btree. If the record identified by P3 and P4 is not the prefix of any entry in P1 then a jump is made to P2. If P1 does contain an entry whose prefix matches the P3/P4 record then control falls through to the next instruction and P1 is left pointing at the matching entry.
This operation leaves the cursor in a state where it cannot be advanced in either direction. In other words, the Next and Prev opcodes do not work after this operation.
2025-04-15 09:52:04 -03:00
Diego Reis
825aeb3f83
core/vdbe: Add BeginSubrtn bytecode
...
Basically it does the very same thing of Null, but has a different name to differentiate its usage.
2025-04-15 09:52:04 -03:00
Jussi Saurio
e299a0e77e
vdbe: add Insn::IdxRowId
2025-04-15 15:13:18 +03:00
Jussi Saurio
5a38b38e71
Merge 'Feature: VDestroy for Dropping Virtual Tables' from Pedro Muniz
...
Reviewed-by: Preston Thorpe (@PThorpe92)
Closes #1274
2025-04-15 14:34:30 +03:00
Jussi Saurio
23f8fffe12
Add Insn::OpenAutoindex, which is just an alias for OpenEphemeral
2025-04-14 11:23:37 +03:00
Jussi Saurio
9dadc58194
Add support for Insn::Once
2025-04-14 11:23:37 +03:00
Jussi Saurio
d286a56e15
refactor: fold Async/Await insns into a single instruction
2025-04-14 09:40:20 +03:00
pedrocarlo
000d8756ec
Implment VDestroy opcode
2025-04-13 17:06:12 -03:00
Diego Reis
fd79ad2644
core/vdbe: Change is_btree to is_table in OpenEphemeral
2025-04-13 11:15:01 -03:00
Diego Reis
66e12e1c2d
core/vdbe: Create OpenEphemeral bytecode
...
"Open a new cursor P1 to a transient table. The cursor is always opened read/write even if the main database is read-only. The ephemeral table is deleted automatically when the cursor is closed.
If the cursor P1 is already opened on an ephemeral table, the table is cleared (all content is erased)."
There is still some work to do, but this is a basic setup
2025-04-13 11:10:06 -03:00
Diego Reis
51eb2af06a
core(refactor): Add CreateBTreeFlags
...
Passing 1s and 0s with comments is not rustacean, and since we already follow the pattern of struct flags in other sections of the codebase it's better use it here too.
2025-04-13 01:46:30 -03:00
Pekka Enberg
31f0d174d7
core/vdbe: Move exec_*() funtions to execute.rs
2025-04-10 09:42:03 +03:00
Pekka Enberg
3fd51cdf06
core/vdbe: Move Insn implementation close to struct definition
2025-04-10 09:28:43 +03:00
Pekka Enberg
5906d7971a
core/vdbe: Clean up imports
2025-04-10 09:25:15 +03:00
Pekka Enberg
a4d9f70ef8
Merge 'Strict table support' from Ihor Andrianov
...
Closes #884
Support for
```CREATE TABLE test(id INTEGER) STRICT;```
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com >
Closes #1268
2025-04-09 16:45:56 +03:00
Jussi Saurio
3e42a62cd0
Add SeekLE/SeekLT operations to VDBE
2025-04-09 10:14:29 +03:00
Ihor Andrianov
4a08b98bab
implemented strict table
2025-04-07 20:01:39 +03:00
jachewz
db15661b7e
fix: i64 % -1 overflow panic
2025-04-07 22:03:48 +10:00
jachewz
a72b75e193
fix: remainder operator rhs text
2025-04-07 22:03:48 +10:00
PThorpe92
83af71f140
Return accidentally deleted comment on SeekGE insn from merge conflict
2025-04-05 11:30:57 -04:00
PThorpe92
e020ba3dfe
Add enum for interpreting a value as a register or literal for insns
2025-04-05 11:19:07 -04:00
PThorpe92
b0016a0ee2
Support create index with SeekEnd and IdxCreate opcode functionality
2025-04-05 11:15:36 -04:00
Diego Reis
38d842d675
docs/insn: Standardizes comments for insn to doc comments
2025-04-04 00:56:54 -03:00
Pekka Enberg
3420955db7
core/vdbe: Rename execute_insn_* to op_*
...
The "execute::execute_insn" prefix is noisy, let's rename the
instruction operation functions to something shorter and sweeter.
2025-04-02 18:02:02 +03:00
Pere Diaz Bou
7e4b57f2e2
VDBE with direct function dispatch
...
This PR is unapologetically stolen from @vmg's implementation in Vitess
implemented here https://github.com/vitessio/vitess/pull/12369 . If you
want a more in depth explanation of how this works you can read the
[blog post he carefully
wrote](https://planetscale.com/blog/faster-interpreters-in-go-catching-up-with-cpp ).
In limbo we have a huge problem with [register
spilling](https://en.wikipedia.org/wiki/Register_allocation ), this can
be easily observed with the prolog of `Program::step` before:
```llvm
start:
%e.i.i304.i = alloca [0 x i8], align 8
%formatter.i305.i = alloca [64 x i8], align 8
%buf.i306.i = alloca [24 x i8], align 8
%formatter.i259.i = alloca [64 x i8], align 8
..................... these are repeated for hundreds of lines
.....................
%formatter.i52.i = alloca [64 x i8], align 8
%buf.i53.i = alloca [24 x i8], align 8
%formatter.i.i = alloca [64 x i8], align 8
%buf.i.i = alloca [24 x i8], align 8
%_87.i = alloca [48 x i8], align 8
%_82.i = alloca [24 x i8], align 8
%_73.i = alloca [24 x i8], align 8
%_66.i8446 = alloca [24 x i8], align 8
%_57.i = alloca [24 x i8], align 8
%_48.i = alloca [24 x i8], align 8
```
After these changes we completely remove the need of register spilling
(yes that is the complete prolog):
```llvm
start:
%self1 = alloca [80 x i8], align 8
%pager = alloca [8 x i8], align 8
%mv_store = alloca [8 x i8], align 8
store ptr %0, ptr %mv_store, align 8
store ptr %1, ptr %pager, align 8
%2 = getelementptr inbounds i8, ptr %state, i64 580
%3 = getelementptr inbounds i8, ptr %state, i64 576
%4 = getelementptr inbounds i8, ptr %self, i64 16
%5 = getelementptr inbounds i8, ptr %self, i64 8
%6 = getelementptr inbounds i8, ptr %self1, i64 8
br label %bb1, !dbg !286780
```
When it comes to branch prediction, we don't really fix a lot because
thankfully rust already compiles `match` expressions
to a jump table:
```llvm
%insn = getelementptr inbounds [0 x %"vdbe::insn::Insn"], ptr %self657,
i64 0, i64 %index, !dbg !249527
%332 = load i8, ptr %insn, align 8, !dbg !249528 , !range !38291 ,
!noundef !14
switch i8 %332, label %default.unreachable26674 [
i8 0, label %bb111
i8 1, label %bb101
i8 2, label %bb100
i8 3, label %bb110
...
i8 104, label %bb5
i8 105, label %bb16
i8 106, label %bb14
], !dbg !249530
```
Some results
----
```
function dispatch:
Execute `SELECT 1`/limbo_execute_select_1
time: [29.498 ns 29.548 ns 29.601 ns]
change: [-3.6125% -3.3592% -3.0804%] (p = 0.00 <
0.05)
main:
Execute `SELECT 1`/limbo_execute_select_1
time: [33.789 ns 33.832 ns 33.878 ns]
```
2025-04-02 14:55:37 +02:00