- Limbo command line shell supports e.g. `SELECT x'616263';`
- `EXPLAIN SELECT x'616263';` lists the opcode
Missing:
- Command line shell not entirely compatible with SQLite when blobs have
non-printable characters in the middle (e.g. `SELECT x'610062';`)
- Python bindings not supported (incoming soon)
### Changes
- Remove clippy warning messages
- Add `#[allow(clippy...)]` in places where it might be better not to
fix
### TODO
recommended changes by `cargo fmt` on my local and github differs on
`sqlite3/src/lib.rs`. Should check for the reason
=> just upgrade the rust toolchain
Closes#329
Related to #144
- Separates `glob` and `like` regex caches, since the same pattern would
result in a different regex depending on which rules you apply
- Also fixes the value of `constant_mask` when translating LIKE
expressions now that non-constant pattern values are supported.
Note that LIKE and GLOB are almost entirely the same, the only
difference being the matching rules (so in our case, the regex
construction).
Closes#334
This reverts commit e365c12ce0, reversing
changes made to 21bd1a961e. The pull request broke some tests:
```
thread 'main' panicked at core/vdbe/mod.rs:1713:72:
index out of bounds: the len is 3 but the index is 3
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
while executing
"exec {*}$command"
(procedure "evaluate_sql" line 3)
invoked from within
"evaluate_sql $sqlite_exec $sql"
(procedure "run_test" line 2)
invoked from within
"run_test $::sqlite_exec $combined_sql $combined_expected_output"
(procedure "do_execsql_test" line 5)
invoked from within
"do_execsql_test sqlite_version {
SELECT sqlite_version();
} {3.46.1}"
(file "./testing/scalar-functions.test" line 434)
invoked from within
"source $testdir/scalar-functions.test"
(file "./testing/all.test" line 16)
make: *** [Makefile:59: test-compat] Error 1
```
### sqlite
<img width="792" alt="image" src="https://github.com/user-
attachments/assets/1a9238db-d948-4583-a808-f9adfec7c534">
### limbo
<img width="809" alt="image" src="https://github.com/user-
attachments/assets/ea3e5f7e-bb3e-450d-be34-59ca00128beb">
### Changes
- Add support for `sqlite_version()` function
- Update function's explain message depending on the number of arguments
Closes#331
Closes#319
1. Allow using a column as the pattern
2. Construct LIKE regexes with `^` and `$` so that eg the string
`'foobar'` does not match the pattern `'fooba'` unless the pattern
specifically has a wildcard
3. Support function expressions as the LIKE pattern
Closes#327
This PR adds a regex cache to `ProgramState` so that we ca re-use
already constructed regexes while processing LIKE expressions. I didn't
find anywhere else that seemed like a good fit to put an execution-time
only cache like this, so let me know if there's a better spot.
To best match sqlite, I added the constant mask into the `Function`
instruction (this indicates whether the first argument to the function
was determined to be constant at compile time), and decide whether to
use the cache based on its value. I've left the value for
`constant_mask` as 0 on every other kind of `Function` instruction. That
seemed to be the safest choice, as that appears to be what has been
implicitly done up to this point. Happy to change that if you'd advise
otherwise.
Fixes#168Closes#320
Reader's guide to this PR:
The aim is to have a more structured and maintainable approach to generating bytecode from the query AST so that different parts of the query processing pipeline have clearer responsibilities, so that developing new functionality is easier. E.g.:
- If you want to implement join reordering -> you do it in `Optimizer`
- If you want to implement `GROUP BY` -> you change `QueryPlanNode::Aggregate` to include it, parse it in `Planner` and handle the code generation for it in `Emitter`
The pipeline is:
`SQL text -> Parser -> Planner -> Optimizer -> Emitter`
and this pipeline generates:
`SQL text -> AST -> Logical Plan -> Optimized Logical Plan -> SQLite Bytecode`
---
Module structure:
`plan.rs`: defines the `Operator` enum. An `Operator` is a tree of other `Operators`, e.g. an `Operator::Join` has `left` and `right` children, etc.
`planner.rs`: Parses an `ast::Select` into a `Plan` which is mainly a wrapper for a root `Operator`
`optimizer.rs`: Makes a new `Plan` from an input `Plan` - does predicate pushdown, constant elimination and turns `Scan` nodes into `SeekRowId` nodes where applicable
`emitter.rs`: Generates bytecode instructions from an input `Plan`.
---
Adds feature `EXPLAIN QUERY PLAN <stmt>` which shows the logical query plan instead of the bytecode plan
---
Other changes:
- Almost everything from `select.rs` removed; things like `translate_aggregation()` moved to `expr.rs`
- `where_clause.rs` removed, some things from it like `translate_condition_expr()` moved to `expr.rs`
- i.e.: there is nothing _new_ in `expr.rs`, stuff just moved there
---
Concerns:
- Perf impact: there's a lot more indirection than before (`Operator`s are very "traditional" trees where they refer to other operators via Boxes etc)
Closes#281