Commit Graph

173 Commits

Author SHA1 Message Date
Pekka Enberg
5de2d91d04 Update COMPAT.md 2025-04-09 17:07:24 +03:00
Pekka Enberg
dbb346ba28 Update COMPAT.md 2025-04-09 17:03:53 +03:00
Pekka Enberg
3b98675aa0 Update COMPAT.md 2025-04-09 17:02:25 +03:00
Duncan Lutz
aa7c64cb19 feat: added likely scalar function 2025-04-06 23:14:30 -06:00
PThorpe92
7567b30d00 Add SeekEnd to compat.md 2025-04-05 11:06:18 -04:00
PThorpe92
293974e692 Update COMPAT.md 2025-04-05 11:06:11 -04:00
Ihor Andrianov
35e1098314 update compat for json functions 2025-03-30 18:58:38 +03:00
Pekka Enberg
31bbc5144a Merge 'Initial pass at UPDATE support' from Preston Thorpe
This PR is to support `Update` queries. Follows sqlite behavior as much
as possible.
### limbo
```console
limbo> create table t (a,b,c);
limbo> explain update t set a = 1 where b = 2;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     18    0                    0   Start at 18
1     OpenWriteAsync     0     2     0                    0
2     OpenWriteAwait     0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     17    0                    0   Rewind table t
5       Column           0     1     4                    0   r[4]=t.b
6       Ne               4     5     15                   0   if r[4]!=r[5] goto 15
7       RowId            0     6     0                    0   r[6]=t.rowid
8       IsNull           6     17    0                    0   if (r[6]==NULL) goto 17
9       Integer          1     1     0                    0   r[1]=1
10      Column           0     1     2                    0   r[2]=t.b
11      Column           0     2     3                    0   r[3]=t.c
12      MakeRecord       1     3     7                    0   r[7]=mkrec(r[1..3])
13      InsertAsync      0     7     6                    0
14      InsertAwait      0     0     0                    0
15    NextAsync          0     0     0                    0
16    NextAwait          0     5     0                    0
17    Halt               0     0     0                    0
18    Transaction        0     1     0                    0   write=true
19    Integer            2     5     0                    0   r[5]=2
20    Goto               0     1     0                    0
```
### sqlite
```console
sqlite> explain update t set a = 1 where b = 2;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     15    0                    0   Start at 15
1     Null           0     1     2                    0   r[1..2]=NULL
2     Noop           1     0     1                    0
3     OpenWrite      0     2     0     2              0   root=2 iDb=0; t
4     Rewind         0     14    0                    0
5       Column         0     1     5                    0   r[5]= cursor 0 column 1
6       Ne             6     13    5     BINARY-8       81  if r[5]!=r[6] goto 13
7       Rowid          0     2     0                    0   r[2]= rowid of 0
8       IsNull         2     14    0                    0   if r[2]==NULL goto 14
9       Integer        1     3     0                    0   r[3]=1
10      Column         0     1     4                    0   r[4]= cursor 0 column 1
11      MakeRecord     3     2     1                    0   r[1]=mkrec(r[3..4])
12      Insert         0     1     2     t              7   intkey=r[2] data=r[1]
13    Next           0     5     0                    1
14    Halt           0     0     0                    0
15    Transaction    0     1     1     0              1   usesStmtJournal=0
16    Integer        2     6     0                    0   r[6]=2
17    Goto           0     1     0                    0
```

Closes #1130
2025-03-24 09:19:22 +02:00
Pekka Enberg
e8c0a6e728 Merge 'Various JSON improvements' from Ihor Andrianov
Added jsonb_object, jsonb_array, json_insert, jsonb_insert.
MongoDB is sweating now.

Closes #1160
2025-03-24 09:17:40 +02:00
PThorpe92
a1d5797f90 Update COMPAT.md 2025-03-23 17:08:15 -04:00
Ihor Andrianov
7710081796 update compat for json functions 2025-03-23 20:59:19 +02:00
Pekka Enberg
c77210aa63 Update COMPAT.md 2025-03-21 13:08:48 +02:00
Ihor Andrianov
f42b62f43c update compat for json functions 2025-03-19 13:00:55 +02:00
Ihor Andrianov
2fb18b4177 update compat 2025-03-17 16:20:43 +02:00
Pekka Enberg
7f2525ac27 Merge 'Implement create virtual table using vtab modules, more work on virtual tables' from Preston Thorpe
This PR started out as one to improve the API of extensions but I ended
up building on top of this quite a bit and it just kept going. Sorry
this one is so large but there wasn't really a good stopping point, as
it kept leaving stuff in broken states.
**VCreate**: Support for `CREATE VIRTUAL TABLE t USING vtab_module`
**VUpdate**: Support for `INSERT` and `DELETE` methods on virtual
tables.
Sqlite uses `xUpdate` function with the `VUpdate` opcode to handle all
insert/update/delete functionality in virtual tables..
have to just document that:
```
if args[0] == NULL:  INSERT args[1] the values in args[2..]

if args[1] == NULL: DELETE args[0]

if args[0] != NULL && len(args) > 2: Update values=args[2..]  rowid=args[0]
```
I know I asked @jussisaurio on discord about this already, but it just
sucked so bad that I added some internal translation so we could expose
a [nice API](https://github.com/tursodatabase/limbo/pull/996/files#diff-
3e8f8a660b11786745b48b528222d11671e9f19fa00a032a4eefb5412e8200d1R54) and
handle the logic ourselves while keeping with sqlite's opcodes.
I'll change it back if I have to, I just thought it was genuinely awful
to have to rely on comments to explain all that to extension authors.
The included extension is not meant to be a legitimately useful one, it
is there for testing purposes. I did something similar in #960 using a
test extension, so I figure when they are both merged, I will go back
and combine them into one since you can do many kinds at once, and that
way it will reduce the amount of crates and therefore compile time.
1. Remaining opcodes.
2. `UPDATE` (when we support the syntax)
3. `xConnect` - expose API for a DB connection to a vtab so it can
perform arbitrary queries.

Closes #996
2025-02-25 15:31:12 +02:00
meteorgan
97337614db extensions/time: normalize offset_sec 2025-02-19 21:25:14 +08:00
PThorpe92
2fd2544f3e Update COMPAT.md 2025-02-17 20:44:44 -05:00
Pekka Enberg
30f700174c Merge 'Added IdxLE and IdxLT opcodes' from Omolola Olamide
I added the two opcodes as an initial step. They are pretty easy to
implement since we already have the counterparts i.e., IdxGE and IdxGT
Is there a design reason behind their omission @penberg @PThorpe92?
I noticed the same for SeekLE and SeekLT.

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

Closes #1010
2025-02-15 11:10:17 +02:00
[B
5214cf9859 Added IdxLE and IdxLT opcodes 2025-02-14 20:22:30 +01:00
Glauber Costa
fbe439f6c2 Implement the legacy_file_format pragma
easy implementation, sqlite claims it is a noop now

"This pragma no longer functions. It has become a no-op. The capabilities
formerly provided by PRAGMA legacy_file_format are now available using
the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option to the sqlite3_db_config()
C-language interface."
2025-02-14 09:50:29 -05:00
Pekka Enberg
64cdfd829e Merge 'core/translate: BEGIN EXCLUSIVE support' from Pekka Enberg
After reading the fine print, SQLite documentation explains that `BEGIN
IMMEDIATE` and `BEGIN EXCLUSIVE` are the same thing in WAL mode:
https://www.sqlite.org/lang_transaction.html
As that's the only mode we support, let's just add code generation for
`BEGIN EXCLUSIVE`.
Fixes #1002

Closes #1003
2025-02-14 12:20:22 +02:00
Pekka Enberg
b949ef5360 Update COMPAT.md 2025-02-14 11:58:54 +02:00
Pekka Enberg
76bdbb54ef core/translate: BEGIN EXCLUSIVE support
After reading the fine print, SQLite documentation explains that `BEGIN
IMMEDIATE` and `BEGIN EXCLUSIVE` are the same thing in WAL mode:

https://www.sqlite.org/lang_transaction.html

As that's the only mode we support, let's just add code generation for
`BEGIN EXCLUSIVE`.

Fixes #1002
2025-02-14 11:52:18 +02:00
Pekka Enberg
5626ca450f core/translate: COMMIT support
```
limbo> EXPLAIN COMMIT;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     3     0                    0   Start at 3
1     AutoCommit         1     0     0                    0   auto_commit=true, rollback=false
2     Halt               0     0     0                    0
3     Goto               0     1     0                    0
```
2025-02-14 10:26:55 +02:00
Pekka Enberg
9fff9f6081 core/translate: BEGIN IMMEDIATE support
Emit the following code sequence for `BEGIN IMMEDIATE`:

```
limbo> EXPLAIN BEGIN IMMEDIATE;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     4     0                    0   Start at 4
1     Transaction        0     1     0                    0
2     AutoCommit         0     0     0                    0   auto_commit=false, rollback=false
3     Halt               0     0     0                    0
4     Goto               0     1     0                    0
```

Please note that SQLite emits *two* transaction instructions -- one for
main database and one for temporary tables. However, since we don't
support the latter, we only emit one transaction instruction.
2025-02-14 10:26:31 +02:00
Pekka Enberg
34b0c7c09a core/vdbe: AutoCommit instruction 2025-02-14 10:26:31 +02:00
Pekka Enberg
5205c23eed Merge 'Initial support for WITH clauses (common table expressions)' from Jussi Saurio
Adds initial limited support for CTEs.
- No MATERIALIZED
- No RECURSIVE
- No named CTE columns
- Only SELECT statements supported inside CTE
Basically this kind of WITH clause can just be rewritten as a subquery,
so this PR adds some plumbing to rewrite them using the existing
subquery machinery.
It also introduces the concept of a `Scope` where a child query can
refer to its parent, useful for CTEs like:
```
do_execsql_test nested-subquery-cte {
    with nested_sub as (
        select concat(name, '!!!') as loud_hat
        from products where name = 'hat'
    ),
    sub as (
        select upper(nested_sub.loud_hat) as loudest_hat from nested_sub
    )
    select sub.loudest_hat from sub;
} {HAT!!!}
```
I think we need to expand the use of `Scope` to all of our identifier
resolutions (currently we don't explicitly have logic for determining
what a given query can see), but I didn't want to bloat the PR too much.
Hence, this implementation is probably full of all sorts of bugs, but
I've added equivalent tests for ALL the existing subquery tests,
rewritten in CTE form.

Closes #920
2025-02-10 12:15:07 +02:00
Pekka Enberg
d221f158cc Merge 'Add read implementation of user_version pragma with ReadCookie opcode' from Jonathan Webb
Just a bare bones implementation of ReadCookie and support for the
user_version pragma

Closes #909
2025-02-10 12:12:15 +02:00
Pekka Enberg
a3875ef130 Update COMPAT.md 2025-02-10 11:25:15 +02:00
Jussi Saurio
6a75266f14 Update COMPAT.MD to include basic CTE support 2025-02-08 14:50:15 +02:00
Jonathan Webb
98e9d33478 Add read implementation of user_version pragma with ReadCookie opcode 2025-02-07 09:23:48 -05:00
pedrocarlo
782a18d4bd modify COMPAT.md 2025-02-06 23:36:02 -03:00
Marcus Nilsson
01492cf46f add support for json_set
Test cases are included.
Related to #127
2025-02-04 19:09:58 +01:00
Pekka Enberg
733f7de688 Merge branch 'main' into feature/time-ext 2025-02-04 18:27:14 +02:00
Pekka Enberg
bf1ef13c91 Merge 'Add Printf Support' from Zaid Humayun
Add basic printf function support in limbo
![Screenshot 2025-02-04 at 8 08 23 PM](https://github.com/user-
attachments/assets/b12931eb-8e79-4c8a-af77-c25c34cc5834)

Closes #886
2025-02-04 17:53:27 +02:00
Zaid Humayun
6a863b3da9 printf: this commit adds support for https://github.com/tursodatabase/limbo/issues/885 tracking printf functionality
this commit introduces basic support for printf functionality and doesn't include advanced modifiers like width etc.
2025-02-04 20:05:14 +05:30
Pekka Enberg
2d9a54ccba Merge 'implement json_pretty' from Pedro Muniz
This PR implements json_pretty. At the moment, support for jsonb is
being added, so this function suffers from the same limitations as in
json(x). Also, I have not found a way to implement the same conversion
of Blob -> String that SQLite does. From my own experimentation, I
believe SQLite converts blobs to a lossy ascii representation, but I
would appreciate some help on this.

Closes #860
2025-02-04 14:51:47 +02:00
pedrocarlo
2e115d948d implement json_pretty 2025-02-01 23:04:46 -03:00
Glauber Costa
a3387cfd5f implement the pragma page_count
To do that, we also have to implement the vdbe opcode Pagecount.
2025-02-01 19:39:46 -05:00
pedrocarlo
9acba9c140 added tests 2025-02-01 16:13:37 -03:00
Pekka Enberg
20d3399c71 Merge 'implement is and is not where constraints' from Glauber Costa
The main difference between = and != is how null values are handled.
SQLite passes a flag "NULLEQ" to Eq and Ne to disambiguate that.
In the presence of that flag, NULL = NULL.
Some prep work is done to make sure we can pass a flag instead of a
boolean to Eq and Ne. I looked into the bitflags crate but got a bit
scared with the list of dependencies.
Warning:
The following query produces a different result for Limbo:
```
select * from demo where value is null or id == 2;
```
I strongly suspect the issue is with the OR implementation, though. The
bytecode generated is quite different.

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

Closes #847
2025-02-01 17:24:11 +02:00
Glauber Costa
3c77797811 also mark IS DISTINCT FROM as supported
This seems to really be just an alias for IS:

"The IS NOT DISTINCT FROM operator is an alternative spelling for the IS
operator. Likewise, the IS DISTINCT FROM operator means the same thing
as IS NOT. Standard SQL does not support the compact IS and IS NOT
notation. Those compact forms are an SQLite extension. You have to use
the prolix and much less readable IS NOT DISTINCT FROM and IS DISTINCT
FROM operators on other SQL database engines."
2025-02-01 09:30:06 -05:00
Pekka Enberg
43d6c2760d Merge 'update compat list' from Glauber Costa
Those two expr seem to be supported

Closes #846
2025-02-01 09:24:27 +02:00
Glauber Costa
96987db6ca implement is and is not where constraints
The main difference between = and != is how null values are handled.
SQLite passes a flag "NULLEQ" to Eq and Ne to disambiguate that.
In the presence of that flag, NULL = NULL.

Some prep work is done to make sure we can pass a flag instead of a
boolean to Eq and Ne. I looked into the bitflags crate but got a bit
scared with the list of dependencies.
2025-01-31 23:01:49 -05:00
Glauber Costa
7e8b190b9a update compat list
Those two expr seem to be supported
2025-01-31 16:56:19 -05:00
Pekka Enberg
44e5402464 Merge branch 'main' into feature/noop 2025-01-31 18:49:39 +02:00
Glauber Costa
a7cc367c1f implement pragma pragma_list
List all available pragmas (Except pragma_list)
2025-01-31 06:44:56 -05:00
Pekka Enberg
7f0274e48f Merge 'Table info' from Glauber Costa
This implements the table_info pragma, allowing us to fetch information
about columns present in a table.

Closes #837
2025-01-31 08:46:27 +02:00
Glauber Costa
016b815b59 implement pragma table_info
Both () and = variants covered. It is important to make sure that
the transaction is a read transaction, so we cannot hide all that logic
inside update_pragma, and have to make our decision before that.
2025-01-30 20:00:20 -05:00
Glauber Costa
598f793581 add compat statement about CreateBTree opcode
It is partially supported - only on the existing database.
2025-01-30 12:52:04 -05:00