Commit Graph

747 Commits

Author SHA1 Message Date
Alex Miller
c4d4569dc9 Merge remote-tracking branch 'upstream/main' into expr-iif 2024-12-11 20:13:54 -08:00
jussisaurio
eb9374aebf Merge 'Add support for CASE expressions.' from Alex Miller
There's two forms of case:
  CASE (WHEN [bool expr] THEN [value])+ (ELSE [value])? END
which checks a series of boolean conditions, and:
  CASE expr (WHEN [expr] THEN [value})+ (ELSE [value])? END
Which checks a series of equality conditions.
This implements support for both. Note that the ELSE is optional, and
will be equivalent to `ELSE null` if not specified.
sqlite3 gives the implementation as:
```
sqlite> explain select case a WHEN a THEN b WHEN c THEN d ELSE 0 END from casetest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     16    0                    0   Start at 16
1     OpenRead       0     3     0     4              0   root=3 iDb=0; casetest
2     Rewind         0     15    0                    0
3       Column         0     0     2                    0   r[2]= cursor 0 column 0
4       Column         0     0     3                    0   r[3]= cursor 0 column 0
5       Ne             3     8     2     BINARY-8       83  if r[2]!=r[3] goto 8
6       Column         0     1     1                    0   r[1]= cursor 0 column 1
7       Goto           0     13    0                    0
8       Column         0     2     3                    0   r[3]= cursor 0 column 2
9       Ne             3     12    2     BINARY-8       83  if r[2]!=r[3] goto 12
10      Column         0     3     1                    0   r[1]= cursor 0 column 3
11      Goto           0     13    0                    0
12      Integer        0     1     0                    0   r[1]=0
13      ResultRow      1     1     0                    0   output=r[1]
14    Next           0     3     0                    1
15    Halt           0     0     0                    0
16    Transaction    0     0     2     0              1   usesStmtJournal=0
17    Goto           0     1     0                    0
```
and after this patch, limbo gives:
```
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     19    0                    0   Start at 19
1     OpenReadAsync      0     4     0                    0   table=casetest, root=4
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     18    0                    0   Rewind table casetest
5       Column           0     0     2                    0   r[2]=casetest.a
6       Column           0     0     3                    0   r[3]=casetest.a
7       Ne               2     3     10                   0   if r[2]!=r[3] goto 10
8       Column           0     1     1                    0   r[1]=casetest.b
9       Goto             0     15    0                    0
10      Column           0     2     3                    0   r[3]=casetest.c
11      Ne               2     3     14                   0   if r[2]!=r[3] goto 14
12      Column           0     3     1                    0   r[1]=casetest.d
13      Goto             0     15    0                    0
14      Integer          0     1     0                    0   r[1]=0
15      ResultRow        1     1     0                    0   output=r[1]
16    NextAsync          0     0     0                    0
17    NextAwait          0     5     0                    0
18    Halt               0     0     0                    0
19    Transaction        0     0     0                    0
20    Goto               0     1     0                    0
```
And then as there's nowhere to annotate this new support in COMPAT.md, I
added a corresponding heading for SELECT expressions and what is/isn't
supported.

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

Closes #425
2024-12-11 17:05:41 +02:00
Pekka Enberg
ab07c77036 Upgrade pprof to 0.14
Github's dependabot complains that the current version has an unsoudness
issue so let's bump to a newer version:

https://github.com/tursodatabase/limbo/security/dependabot/10
2024-12-11 11:21:09 +02:00
Pekka Enberg
04f196113a Merge 'Add last_insert_rowid() function' from Krishna Vishal
- Changed `Cursor` trait to be able to get access to `root_page`
- SQLite only updates last_insert_rowid for non-schema inserts. So we
check if the `InsertAwait` is not for `root_page` before   updating
rowid
In SQLite it looks like this:
```
sqlite> EXPLAIN SELECT last_insert_rowid();
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     4     0                    0
1     Function       0     0     1     last_insert_rowid(0) 0
2     ResultRow      1     1     0                    0
3     Halt           0     0     0                    0
4     Goto           0     1     0                    0
```
In limbo it will look like this:
```
limbo> EXPLAIN SELECT last_insert_rowid();
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     4     0                    0   Start at 4
1     Function           0     2     1     last_insert_rowid  0   r[1]=func()
2     ResultRow          1     1     0                    0   output=r[1]
3     Halt               0     0     0                    0
4     Transaction        0     0     0                    0
5     Goto               0     1     0                    0
```

Closes #427
2024-12-11 10:44:34 +02:00
Pekka Enberg
ca272ba937 Merge 'Support JOIN USING and NATURAL JOIN' from Jussi Saurio
Closes #360
Closes #361

Closes #422
2024-12-11 09:17:51 +02:00
Pekka Enberg
eda1f5396c Merge 'Add octet_length scalar function' from Kacper Kołodziej
Adds `octet_length` scalar function.
Part of solution for: #144

Closes #430
2024-12-11 07:44:04 +02:00
Alex Miller
88c862ce4d Comments, resolve label better, make tests more fun 2024-12-10 19:59:54 -08:00
Alex Miller
e85df1c895 resolve labels to current offset. make test clearer. 2024-12-10 19:36:54 -08:00
Kacper Kołodziej
d4bff2c93e add octet_length scalar function 2024-12-10 22:56:38 +01:00
Kacper Kołodziej
660d3e8d07 fix: count characters in string in length function
`length` function should count characters, not bytes.

https://www.sqlite.org/lang_corefunc.html#length
2024-12-10 22:48:50 +01:00
krishvishal
134b5576ad Ran cargo fmt 2024-12-09 22:55:54 +05:30
krishvishal
7e2928a5f1 Feature: last_insert_rowid()
- Changed `Cursor` trait to be able to get access to `root_page`
- SQLite only updates last_insert_rowid for non-schema inserts. So we check if the `InsertAwait` is not for `root_page` before
  updating rowid
2024-12-09 22:48:42 +05:30
jussisaurio
fe88d45e5e Add more comments to push_predicate/push_predicates 2024-12-09 17:50:29 +02:00
jussisaurio
840caed2f7 Fix bug with multiway joins that include the same table multiple times 2024-12-09 17:50:29 +02:00
jussisaurio
7924f9b64d consider all joined tables instead of just previous in natural/using 2024-12-09 17:50:29 +02:00
jussisaurio
81b6605453 support NATURAL JOIN 2024-12-09 17:50:29 +02:00
jussisaurio
bed932c186 Support join USING 2024-12-09 17:50:29 +02:00
Pekka Enberg
ba1f7cd16f Merge 'feat(core/translate): support HAVING' from Jussi Saurio
support the HAVING clause.
note that sqlite (and i think standard sql?) supports HAVING even
without GROUP BY, but `sqlite3-parser` doesn't.
also fixes some issues with the PartialOrd implementation of OwnedValue
and the implementations of `concat` and `round` which i discovered due
to my HAVING tcl tests failing

Closes #420
2024-12-09 17:30:40 +02:00
krishvishal
1e23af7d24 Added last_insert_rowid() function.
Need to fix its behavior. Problem is probably with `Cursor` implementation.
2024-12-09 17:41:28 +05:30
Alex Miller
f7bb7f8dee Fix typo and improve comment 2024-12-08 14:20:23 -08:00
Alex Miller
c2e3957d73 I misunderstood what a constant instruction was 2024-12-08 14:12:45 -08:00
Alex Miller
eb00226cfe Add support for CASE expressions.
There's two forms of case:
  CASE (WHEN [bool expr] THEN [value])+ (ELSE [value])? END
which checks a series of boolean conditions, and:
  CASE expr (WHEN [expr] THEN [value})+ (ELSE [value])? END
Which checks a series of equality conditions.

This implements support for both. Note that the ELSE is optional, and
will be equivalent to `ELSE null` if not specified.

sqlite3 gives the implementation as:

sqlite> explain select case a WHEN a THEN b WHEN c THEN d ELSE 0 END from casetest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     16    0                    0   Start at 16
1     OpenRead       0     3     0     4              0   root=3 iDb=0; casetest
2     Rewind         0     15    0                    0
3       Column         0     0     2                    0   r[2]= cursor 0 column 0
4       Column         0     0     3                    0   r[3]= cursor 0 column 0
5       Ne             3     8     2     BINARY-8       83  if r[2]!=r[3] goto 8
6       Column         0     1     1                    0   r[1]= cursor 0 column 1
7       Goto           0     13    0                    0
8       Column         0     2     3                    0   r[3]= cursor 0 column 2
9       Ne             3     12    2     BINARY-8       83  if r[2]!=r[3] goto 12
10      Column         0     3     1                    0   r[1]= cursor 0 column 3
11      Goto           0     13    0                    0
12      Integer        0     1     0                    0   r[1]=0
13      ResultRow      1     1     0                    0   output=r[1]
14    Next           0     3     0                    1
15    Halt           0     0     0                    0
16    Transaction    0     0     2     0              1   usesStmtJournal=0
17    Goto           0     1     0                    0

and after this patch, limbo gives:

addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     18    0                    0   Start at 18
1     OpenReadAsync      0     4     0                    0   table=casetest, root=4
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     17    0                    0   Rewind table casetest
5       Column           0     0     2                    0   r[2]=casetest.a
6       Column           0     0     3                    0   r[3]=casetest.a
7       Ne               2     3     10                   0   if r[2]!=r[3] goto 10
8       Column           0     1     1                    0   r[1]=casetest.b
9       Goto             0     14    0                    0
10      Column           0     2     3                    0   r[3]=casetest.c
11      Ne               2     3     14                   0   if r[2]!=r[3] goto 14
12      Column           0     3     1                    0   r[1]=casetest.d
13      Goto             0     14    0                    0
14      ResultRow        1     1     0                    0   output=r[1]
15    NextAsync          0     0     0                    0
16    NextAwait          0     5     0                    0
17    Halt               0     0     0                    0
18    Transaction        0     0     0                    0
19    Integer            0     1     0                    0   r[1]=0
20    Goto               0     1     0                    0

And then as there's nowhere to annotate this new support in COMPAT.md, I
added a corresponding heading for SELECT expressions and what is/isn't
supported.
2024-12-08 14:09:03 -08:00
Alex Miller
27ef95e0ab LLM recommended a better way to write args matching 2024-12-07 21:15:04 -08:00
Alex Miller
183ea8e362 Implement support for iif().
In sqlite, iif() looks like:

sqlite> create table iiftest(a int, b int, c int);
sqlite> explain select iif(a,b,c) from iiftest;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     11    0                    0   Start at 11
1     OpenRead       0     2     0     3              0   root=2 iDb=0; iiftest
2     Rewind         0     10    0                    0
3       Column         0     0     2                    0   r[2]= cursor 0 column 0
4       IfNot          2     7     1                    0
5       Column         0     1     1                    0   r[1]= cursor 0 column 1
6       Goto           0     8     0                    0
7       Column         0     2     1                    0   r[1]= cursor 0 column 2
8       ResultRow      1     1     0                    0   output=r[1]
9     Next           0     3     0                    1
10    Halt           0     0     0                    0
11    Transaction    0     0     1     0              1   usesStmtJournal=0
12    Goto           0     1     0                    0

And with this change, in limbo it looks like:

addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     14    0                    0   Start at 14
1     OpenReadAsync      0     2     0                    0   table=iiftest, root=2
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     13    0                    0   Rewind table iiftest
5       Column           0     0     2                    0   r[2]=iiftest.a
6       IfNot            2     9     1                    0   if !r[2] goto 9
7       Column           0     1     1                    0   r[1]=iiftest.b
8       Goto             0     10    0                    0
9       Column           0     2     1                    0   r[1]=iiftest.c
10      ResultRow        1     1     0                    0   output=r[1]
11    NextAsync          0     0     0                    0
12    NextAwait          0     5     0                    0
13    Halt               0     0     0                    0
14    Transaction        0     0     0                    0
15    Goto               0     1     0                    0
2024-12-07 21:04:03 -08:00
jussisaurio
ca25a73c95 a little bit more explanation about left join handling 2024-11-30 20:54:22 +02:00
jussisaurio
83f8ea1b13 Fix bug with multiway joins and clean up left join implementation 2024-11-30 20:47:48 +02:00
jussisaurio
3f80e41e7a support HAVING 2024-11-30 10:05:13 +02:00
jussisaurio
84742b81fa Obsolete comment 2024-11-27 22:43:36 +02:00
jussisaurio
da811dc403 add doc comments for members of Plan struct 2024-11-27 19:30:07 +02:00
jussisaurio
db462530f1 metadata instead of m 2024-11-27 19:27:36 +02:00
jussisaurio
7d569aee1f fix stupid comment 2024-11-26 18:37:06 +02:00
jussisaurio
1b34698872 add comments and rename some misleading label variables 2024-11-26 18:28:19 +02:00
jussisaurio
7f04f8e88f rename 2024-11-26 17:41:08 +02:00
jussisaurio
122546444f extract function order_by_sorter_insert() 2024-11-26 17:40:49 +02:00
jussisaurio
3d27ef90f5 emitting result columns generally works the same way -> extract it 2024-11-26 17:31:51 +02:00
jussisaurio
c74981873e Extract ORDER BY result column deduping into a function 2024-11-26 17:31:51 +02:00
jussisaurio
89569fa7a3 Remove redundant if-else after refactoring ResultSetColumn to struct 2024-11-26 17:31:51 +02:00
jussisaurio
ac12e9c7fd No need for ResultSetColumn to be an enum 2024-11-26 17:31:51 +02:00
jussisaurio
7d5fa12bb7 fix allocating wrong number of registers upfront for aggregation results 2024-11-26 17:31:51 +02:00
jussisaurio
56b15193d0 resolve aggregates from orderby as well 2024-11-26 17:31:51 +02:00
jussisaurio
885b6ecd76 Remove 'cursor_hint': it is never needed 2024-11-26 17:31:51 +02:00
jussisaurio
008be10cfd Add TODO about expression equality comparisons 2024-11-26 17:31:51 +02:00
jussisaurio
cfb7e79601 Function doc comments 2024-11-26 17:31:51 +02:00
jussisaurio
fc33c70481 remove many unnecessary fields from SortMetadata and GroupByMetadata 2024-11-26 17:31:51 +02:00
jussisaurio
ebce78bcd9 rename 2024-11-26 17:31:51 +02:00
jussisaurio
0510e150d3 fix comment 2024-11-26 17:31:51 +02:00
jussisaurio
1c37d8b24b extract function sorter_insert() 2024-11-26 17:31:51 +02:00
jussisaurio
4f3da982c0 extract function emit_result_row() 2024-11-26 17:31:51 +02:00
jussisaurio
52beeabd45 tweaks 2024-11-26 17:31:51 +02:00
jussisaurio
120601f732 fix metadata comments 2024-11-26 17:31:51 +02:00