Commit Graph

1636 Commits

Author SHA1 Message Date
Pekka Enberg
fc60e544af Merge 'Fix arithmetic operations for text values' from Vrishabh
We had not implemented arithmetic operations for text values. This PR
implements this and aligns the behavior with sqlite3 .

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

Closes #605
2025-01-04 13:40:03 +02:00
Pekka Enberg
bae452f6b0 Merge 'sqlite3: Add in-memory support to sqlite3_open()' from Pekka Enberg
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #606
2025-01-04 13:39:58 +02:00
Pekka Enberg
0238eaf95d Merge 'Emitter cleanup part 2' from Jussi Saurio
Changes:
---
Instead of passing around:
    1. `SymbolTable` (for resolving functions dynamically provided by
extensions), and
    2. `precomputed_exprs_to_registers` (for resolving registers
containing results from already-computed expressions),
add `Resolver` struct to `TranslateCtx` that encapsulates both.
This introduces some lifetime annotation spam unfortunately, but maybe
we can also migrate to using references instead of cloning elsewhere as
well, since we generally do a lot of copying of expressions right now
for convenience.
---
Use way less arguments to functions - mainly just passing `program`,
`t_ctx` and `plan` around.

Closes #609
2025-01-04 13:27:38 +02:00
Jussi Saurio
e31317fbb5 emitter.rs: use way less arguments to functions 2025-01-04 12:59:30 +02:00
Jussi Saurio
d2b73e8492 emitter.rs: make t_ctx always be the second argument to any functions 2025-01-04 12:32:50 +02:00
Jussi Saurio
d1f74fa3cb Emitter cleanup part 2: add Resolver 2025-01-04 12:23:19 +02:00
Pekka Enberg
08844b80bb Merge 'Code cleanups to emitter' from Jussi Saurio
I plan to do a series of cleanups to `emitter.rs` which is a chonker
module right now. This first one is just making some variable namings
more consistent and refactoring some metadata fields to function-local
variables

Closes #604
2025-01-04 11:03:52 +02:00
Pekka Enberg
276819369c sqlite3: Add in-memory support to sqlite3_open() 2025-01-04 10:58:51 +02:00
Jussi Saurio
23f1858239 translatectx: consistent naming 2025-01-04 10:39:32 +02:00
Jussi Saurio
1a01487872 left join metadata: consistent naming 2025-01-04 10:39:32 +02:00
Jussi Saurio
2f129402e8 sorter data register: consistent naming 2025-01-04 10:39:32 +02:00
Jussi Saurio
0c572cda3c more consistent function naming 2025-01-04 10:39:32 +02:00
Jussi Saurio
9c1d952e3b consistent names for group by regs and labels 2025-01-04 10:39:32 +02:00
Jussi Saurio
28b1754cf4 group_by_emit: add comments to labels and registers 2025-01-04 10:39:32 +02:00
Jussi Saurio
9ccbb69618 remove fields from GroupByMetadata that can be function-local 2025-01-04 10:39:32 +02:00
Pekka Enberg
bd5f081ea8 Merge 'Add support for changes() and total_changes() functions' from Lemon-Peppermint
#525
- Adds the necessary `ScalarFunc` variants to support the `changes()` &
`total_changes()` SQLite function.
- Adds the necessary fields to the `Connection` struct to track changes.
- Modify the `InsertAwait` OpCode behaviour to affect the changes
counter.

Closes #589
2025-01-04 10:14:06 +02:00
Pekka Enberg
b5e95d7b5d Merge 'Remove SQLite headers dependency from compat tests' from dkaluza
* Add SQLITE_FLAGS env variable handling to compatibility tests as
SQLite does not handle `-q` flag
* Fix inconsistent SQLITE_NOTFOUND error code and add SQLITE_CANTOPEN
code
* Improve compatibility tests to display errors instead of hanging
indefinitely

Closes #599
2025-01-04 10:12:28 +02:00
Pekka Enberg
3ddbb4bdea Merge 'Add CSV import support to shell' from Vrishabh
I was trying to get limbo to a position where we can run the benchmark [
clickbench](https://github.com/ClickHouse/ClickBench/blob/main/sqlite/be
nchmark.sh)  and found that `.import` command was not supported in cli.
This PR adds that support for command `.import` which has the same
parameters as sqlite cli.
Do note that not all options from sqlite `.import` is implemented yet in
this PR.

Reviewed-by: Preston Thorpe <preston@unlockedlabs.org>

Closes #598
2025-01-04 10:11:41 +02:00
Pekka Enberg
cc6c8b076a Merge 'docs: fix url to tursodatabase' from Todsaporn Banjerdkit
Closes #601
2025-01-04 10:10:59 +02:00
katopz
14657137eb docs: fix url to tursodatabase 2025-01-04 16:30:32 +09:00
Jussi Saurio
a934ead904 Merge 'Json extract' from Kacper Madej
Implements the `json_extract` function.
In the meantime, the json path has already been implemented by
@petersooley in https://github.com/tursodatabase/limbo/pull/555 which is
a requirement for `json_extract`.
However, this PR takes a different approach and parses the JSON path
using the JSON grammar, because there are a lot of quirks in how a JSON
`key` can look (see the JSON grammar in the Pest file).
The downside is that it allocates more memory than the current
implementation, but might be easier to maintain in the long run.
I included a lot of tests with some quirky behavior of the
`json_extract` (some of them still need some work). I also noticed that
these changed between sqlite versions (had `SQLite 3.43.2` locally and
`3.45` gave different results). Due to this, I'm not sure how much value
there is in trying to be fully compatible with SQLite. Perhaps the
approach taken by @petersooley solves 99% of use-cases?

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

Closes #524
2025-01-03 23:53:29 +02:00
Jussi Saurio
0fefffbbcb Merge 'fix: index seek wrong on SeekOp::LT\SeekOp::GT' from Kould
data does not match predicate when using index, e.g: `select id, age
from users where age > 90 limit 1;` will return data with age  90
the reason is that the current index seek directly uses record for
comparison, but the record of the index itself is longer than the record
of the key (because it contains the primary key), so Gt is invalid.
since only single-column indexes are currently supported:
https://github.com/tursodatabase/limbo/pull/350, only the first value of
the record is currently used for comparison.

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

Closes #593
2025-01-03 23:27:24 +02:00
psvri
2b879a4f40 Fix arithmetic operations for text values 2025-01-04 00:34:04 +05:30
psvri
18a1055088 Edit help message 2025-01-03 19:40:35 +05:30
Daniel Kaluza
9ab0e90807 Fix compatibility tests not showing errors and hanging indefinitely in case of error 2025-01-03 11:19:21 +01:00
Daniel Kaluza
3b85015f55 Fix inconsistent SQLITE_NOTFOUND error code 2025-01-03 11:19:21 +01:00
Daniel Kaluza
34690e3b63 Remove dependency on system libsqlite headers from compatibility tests 2025-01-03 11:19:21 +01:00
psvri
1f21cf6a71 Feat: Import csv support 2025-01-03 15:20:22 +05:30
Lemon-Peppermint
9109dbf8ec Add changes tracking to the 'Connection' struct + 'Insn::InsertAwait' now affects changes counter 2025-01-03 00:04:20 +02:00
Lemon-Peppermint
abd8e6af43 Add early 'changes()' & 'total_changes()' support 2025-01-02 23:35:19 +02:00
Kould
a33984087f chore: add comment on BTreeCursor::seek 2025-01-02 18:18:17 +08:00
Pekka Enberg
90d01f468f Merge 'Support uncorrelated FROM clause subqueries' from Jussi Saurio
I will warn that this PR is quite big out of necessity, since subqueries
are, as the name implies, queries within queries, so everything that
works with a regular query should also work with a subquery, roughly
speaking.
---
- Adds support for:
    * uncorrelated subqueries in FROM clause (i.e. appear as a "table",
and do not refer to outer tables). Example of this at the end of the PR
description.
    * column and subquery aliasing (`select sub.renamed from (select
name as renamed from products) sub`)
    * inner and outer filtering of subqueries (`select sub.name from
(select name from products where name = 'joe') sub`, and,  `select
sub.name from (select name from products) sub where sub.name = 'joe'`)
    * joining between regular tables and subqueries
    * joining between multiple subqueries
    * in general working with subqueries should roughly equal working
with regular tables
- Main idea: subqueries are just wrappers of a `SelectPlan` that never
emit ResultRows, instead they `Yield` control back to the parent query,
and the parent query can copy the subquery result values into a
ResultRow. New variant `SourceOperator::Subquery` that wraps a subquery
`SelectPlan`.
- Plans can now not only refer to btree tables (`select p.name from
products`) but also subqueries (`select sub.foo from (select name as foo
from products) sub`. Hence this PR also adds support for column aliases
which didn't exist before.
    * An `Expr::Column` that refers to a regular table will result in an
`Insn::Column` (i.e. a read from disk/memory) whereas an `Expr::Column`
that refers to a subquery will result in an `Insn::Copy` (from register
to register) instead
- Subquery handling is entirely unoptimized, there's no predicate
pushdown from outer query to subqueries, or elimination of redundant
subqueries (e.g. in the trivial example `SELECT * FROM (SELECT * FROM
users) sub` the subquery can just be entirely removed)
---
This PR does not add support (yet) for:
- subqueries in result columns: `SELECT t.foo, (SELECT .......) as
column_from_subquery FROM t`
- subqueries in WHERE clauses e.g. `SELECT * FROM t1 WHERE t1.foo IN
(SELECT ...)`
- subquery-related optimizations, of which there are plenty available.
No analysis is done regarding e.g. whether predicates on the outer query
level could be pushed into the subquery, or whether the subquery could
be entirely eliminated. Both of the above can probably be done fairly
easily for a bunch of trivial cases.
---
Example bytecode with comments added:
```
limbo> EXPLAIN SELECT p.name, sub.funny_name FROM products p JOIN (
  select id, concat(name, '-lol') as funny_name from products
) sub USING (id) LIMIT 3;

addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     31    0                    0   Start at 31

// Coroutine implementation starts at insn 2, jump immediately to 14
1     InitCoroutine      1     14    2                    0

2     OpenReadAsync      0     3     0                    0   table=products, root=3
3     OpenReadAwait      0     0     0                    0
4     RewindAsync        0     0     0                    0
5     RewindAwait        0     13    0                    0   Rewind table products
6       RowId            0     2     0                    0   r[2]=products.rowid
7       Column           0     1     4                    0   r[4]=products.name
8       String8          0     5     0     -lol           0   r[5]='-lol'
9       Function         0     4     3     concat         0   r[3]=func(r[4..5])

// jump back to main loop of query (insn 20)
10      Yield            1     0     0                    0

11    NextAsync          0     0     0                    0
12    NextAwait          0     6     0                    0
13    EndCoroutine       1     0     0                    0
14    OpenReadAsync      1     3     0                    0   table=p, root=3
15    OpenReadAwait      0     0     0                    0
16    RewindAsync        1     0     0                    0
17    RewindAwait        1     30    0                    0   Rewind table p

// Since this subquery is the inner loop of the join, reinitialize it on every iteration of the outer loop
18      InitCoroutine    1     0     2                    0

// Jump back to the subquery implementation to assign another row into registers
19      Yield            1     28    0                    0

20      RowId            1     8     0                    0   r[8]=p.rowid

// Copy sub.id
21      Copy             2     9     0                    0   r[9]=r[2]

// p.id == sub.id?
22      Ne               8     9     27                   0   if r[8]!=r[9] goto 27
23      Column           1     1     6                    0   r[6]=p.name

// copy sub.funny_name
24      Copy             3     7     0                    0   r[7]=r[3]

25      ResultRow        6     2     0                    0   output=r[6..7]
26      DecrJumpZero     10    30    0                    0   if (--r[10]==0) goto 30
27      Goto             0     19    0                    0
28    NextAsync          1     0     0                    0
29    NextAwait          1     18    0                    0
30    Halt               0     0     0                    0
31    Transaction        0     0     0                    0
32    Integer            3     10    0                    0   r[10]=3
33    Goto               0     1     0                    0
```

Closes #566
2025-01-02 11:15:07 +02:00
Pekka Enberg
1ec8d472ca Merge 'Minor clippy fixes for windows platform' from Vrishabh
Just fixes a few clippy errors on the windows platform

Closes #591
2025-01-02 11:12:52 +02:00
Kacper Madej
92af5b4544 Fix build 2025-01-02 15:09:20 +07:00
Kacper Madej
f27f873804 PR remarks #2 2025-01-02 15:09:16 +07:00
Kacper Madej
4fc1b66225 Merge branch 'main' into json-extract 2025-01-02 15:04:16 +07:00
Kacper Madej
7553d3684a Assert specific error in tests 2025-01-02 15:01:43 +07:00
Kacper Madej
7d7d202ffe PR remarks 2025-01-02 14:41:47 +07:00
Kould
e5d0ad044e fix: index seek wrong 2025-01-02 11:11:44 +08:00
psvri
e7d4fa0a53 Minor clippy fixes 2025-01-01 16:11:52 +05:30
Jussi Saurio
df6c8c9dd1 comment about yield instruction 2025-01-01 08:22:47 +02:00
Jussi Saurio
776ffc6131 assert instead of fallback 2025-01-01 08:21:20 +02:00
Jussi Saurio
3e5be21707 remove commented out code 2025-01-01 08:18:49 +02:00
Jussi Saurio
2b5b54c44e clippy 2025-01-01 07:56:39 +02:00
Jussi Saurio
6633a3c66a condense comment 2025-01-01 07:56:39 +02:00
Jussi Saurio
80b9da95c0 replace termination_label_stack with much simpler LoopLabels 2025-01-01 07:56:39 +02:00
Jussi Saurio
1bc1f38737 Merge 'Refactor out repetitive agg_func code in vdbe' from Preston Thorpe
This PR cleans up a lot of the repetitive code that caused having to
match the `AggFunc` cases repeatedly 😄
Most of the repetition was caused by the binary math operators, so I
just added it for those for now.

Reviewed-by: Jussi Saurio <penberg@iki.fi>
Reviewed-by: Pere Diaz Bou <preston@unlockedlabs.org>

Closes #575
2024-12-31 15:02:57 +02:00
PThorpe92
ed95007298 Separate exec insns to individual functions 2024-12-31 07:55:40 -05:00
PThorpe92
45eeee1589 Add comment and match case for improperly called values 2024-12-31 07:54:01 -05:00
PThorpe92
d572089b80 Refactor out repetitive agg_func code in vdbe 2024-12-31 07:53:55 -05:00