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
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
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."
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#1002Closes#1003
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
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.
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