Commit Graph

86 Commits

Author SHA1 Message Date
Jussi Saurio
330fedbc2f Add notion of join ordering to plan + make determining where to eval expr dynamic always 2025-05-03 15:32:06 +03:00
Jussi Saurio
306e097950 Merge 'Fix bug: we cant remove order by terms from the head of the list' from Jussi Saurio
we had an incorrect optimization in `eliminate_orderby_like_groupby()`
where it could remove e.g. the first term of the ORDER BY if it matched
the first GROUP BY term and the result set was naturally ordered by that
term. this is invalid. see e.g.:
```sql
main branch - BAD: removes the `ORDER BY id` term because the results are naturally ordered by id.
However, this results in sorting the entire thing by last name only!

limbo> select id, last_name, count(1) from users GROUP BY 1,2 order by id, last_name desc limit 3;
┌──────┬───────────┬───────────┐
│ id   │ last_name │ count (1) │
├──────┼───────────┼───────────┤
│ 6235 │ Zuniga    │         1 │
├──────┼───────────┼───────────┤
│ 8043 │ Zuniga    │         1 │
├──────┼───────────┼───────────┤
│  944 │ Zimmerman │         1 │
└──────┴───────────┴───────────┘

after fix - GOOD:

limbo> select id, last_name, count(1) from users GROUP BY 1,2 order by id, last_name desc limit 3;
┌────┬───────────┬───────────┐
│ id │ last_name │ count (1) │
├────┼───────────┼───────────┤
│  1 │ Foster    │         1 │
├────┼───────────┼───────────┤
│  2 │ Salazar   │         1 │
├────┼───────────┼───────────┤
│  3 │ Perry     │         1 │
└────┴───────────┴───────────┘

I also refactored sorters to always use the ast `SortOrder` instead of boolean vectors, and use the `compare_immutable()` utility we use inside btrees too.

Closes #1365
2025-05-03 12:48:08 +03:00
Jussi Saurio
e5bab63522 add expr.is_constant() 2025-04-24 11:05:21 +03:00
Jussi Saurio
b36c898842 rename check_constant() to less confusing name 2025-04-24 11:05:21 +03:00
Jussi Saurio
3798b4aa8b use SortOrder in sorters always 2025-04-24 10:34:06 +03:00
Jussi Saurio
f53448ae75 Fix bug: we cant remove order by terms from the head of the list 2025-04-24 10:34:06 +03:00
Jussi Saurio
a7488496d5 expr.is_nonnull(): return true if col.primary_key || col.notnull 2025-04-23 18:10:33 +03:00
Jussi Saurio
3b44b269a3 optimizer: try to build ephemeral index to avoid nested table scan 2025-04-21 14:59:13 +03:00
Jussi Saurio
6924424f11 optimizer: add highly unintelligent heuristics-based cost estimation 2025-04-21 14:59:13 +03:00
Jussi Saurio
a50fa03d24 optimizer: allow calling try_extract_index... without any persistent indexes 2025-04-21 14:59:13 +03:00
Jussi Saurio
6c73db6fd3 feat: use covering indexes whenever possible 2025-04-18 15:13:09 +03:00
Jussi Saurio
5b71d3a3da eliminate_unnecessary_orderby: add edge case handling 2025-04-18 15:12:06 +03:00
Jussi Saurio
1189b7a288 codegen: add support for descending indexes 2025-04-16 13:58:12 +03:00
Jussi Saurio
a467060e1c Index: add method column_table_pos_to_index_pos() 2025-04-15 14:47:56 +03:00
Jussi Saurio
0d97e2a311 Fix not using index when expr is paren-wrapped: e.g. SELECT * FROM t WHERE (x > 5) 2025-04-12 11:13:33 +03:00
Jussi Saurio
c6bea835f9 Fix trying to use index when both sides of comparison refer to same table 2025-04-12 11:13:33 +03:00
Jussi Saurio
6bea4de30f Check that index seek key members are not null 2025-04-11 17:22:46 +03:00
Jussi Saurio
4daad0a858 Fix bug: accidentally skipped index selection for other tables except first found 2025-04-10 18:57:14 +03:00
Jussi Saurio
457bded14d optimizer: refactor optimizer to support multicolumn index scans 2025-04-10 15:53:02 +03:00
Jussi Saurio
3124fca5b7 Dereference instead of explicit clone 2025-04-09 10:14:29 +03:00
Jussi Saurio
024c63f808 optimizer: remove ORDER BY if index can be used to satisfy the order 2025-04-09 10:14:29 +03:00
Ihor Andrianov
91ceab1626 improve naming and add comments for context 2025-04-03 22:28:13 +03:00
Ihor Andrianov
816cbacc9c some smartie optimizations 2025-04-03 22:28:12 +03:00
PThorpe92
3fe14f37a5 Create plan for Update queries 2025-03-30 12:15:24 -04:00
Pere Diaz Bou
e4a8ee5402 move load extensions to Connection
Extensions are loaded per connection and not per database as per SQLite
behaviour. This also helps with removing locks.
2025-03-05 14:07:48 +01:00
Pere Diaz Bou
8daf7666d1 Make database Sync + Send 2025-03-05 14:07:48 +01:00
Jussi Saurio
8e5499e5ed Fix not evaling constant conditions when no tables in query
We were not evaluating constant conditions (e.g '1 IS NULL')
when there were no tables referenced in the query, because
our WHERE term evaluation was based on "during which loop"
to evaluate them. However, when there are no tables, there are
no loops, so they were never evaluated.
2025-02-17 13:10:27 +02:00
Jussi Saurio
447f91e5ee optimizer.rs: remove constant folding optimization for NULL since it's incorrect 2025-02-17 07:43:09 +02:00
Pekka Enberg
ac54c35f92 Switch to workspace dependencies
...makes it easier to specify a version, which is needed for `cargo publish`.
2025-02-12 17:28:04 +02:00
PThorpe92
d4c06545e1 Refactor vtable impl and remove Rc Refcell from module 2025-02-06 09:15:39 -05:00
Jussi Saurio
f5f77c0bd1 Initial virtual table implementation 2025-02-06 07:51:50 -05:00
Jussi Saurio
795576b2ec dont eagerly allocate result column name strings 2025-02-05 17:53:23 +02:00
Jussi Saurio
750a9c6463 assertions and small cleanups 2025-02-03 13:08:13 +02:00
Jussi Saurio
40f536fabb Dont store available_indexes on plan; only used in optimize_plan() 2025-02-03 12:52:14 +02:00
Jussi Saurio
d4cb0a1223 Merge 'Fix logical codegen' from Nikita Sivukhin
Fix few logical codegen issues and add fuzz tests for logical
expressions
-  Right now Limbo fails to recognize `false` constant in case when any
unary operator is used on the AST path. This PR add unary operator
option in the rewrite code and handle such cases properly.
```sql
limbo> SELECT NOT FALSE;

  × Parse error: no such column: FALSE - should this be a string literal in single-quotes?

```
- `ifnull` implementation produced incorrect codegen due to "careless"
management of registers
```
limbo> SELECT ifnull(0, NOT 0)
[NULL here]
```
- `like` implementation produced incorrect codegen due to "careless"
management of registers
```
limbo> SELECT like('a%', 'a') = 1;
thread 'main' panicked at core/vdbe/mod.rs:1902:41:
internal error: entered unreachable code: Like on non-text registers
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
Depends on https://github.com/tursodatabase/limbo/pull/867 (need
`GrammarGenerator` from this branch)

Closes #869
2025-02-03 12:39:41 +02:00
Nikita Sivukhin
a4a80f37bc rewrite unary expressions too - in order to support "NOT FALSE" expressions 2025-02-03 11:25:14 +04:00
Nikita Sivukhin
5a3587f7a2 use opposite operator for search if WHERE condition is swapped (e.g. 1 > x instead of x < 1) 2025-02-03 11:23:04 +04:00
Pekka Enberg
662d629666 Rename JoinAwareConditionExpr to WhereTerm
We transform all JOIN conditions into WHERE clause terms in the query
planner. The JoinAwareConditionExpr name tries to make that point, but I
think it makes things more confusing. Let's call it WhereTerm (suggested
by Jussi).
2025-02-03 07:46:51 +02:00
Jussi Saurio
98439cd936 optimizer.rs: refactor to use new data structures and remove unnecessary stuff
We don't need `push_predicates()` because that never REALLY was a predicate
pushdown optimization -- it just pushed WHERE clause condition expressions
into the correct SourceOperator nodes in the tree.

Now that we don't have a SourceOperator tree anymore and we keep the conditions
in the WHERE clause instead, we don't need to "push" anything anymore. Leaves
room for ACTUAL predicate pushdown optimizations later :)

We also don't need any weird bitmask stuff anymore, and perhaps we never did,
to determine where conditions should be evaluated.
2025-02-02 10:18:13 +02:00
Jussi Saurio
1bcdf99eab core/optimizer: do expression rewriting on all expressions 2025-01-10 10:04:07 +02:00
Jussi Saurio
925bd62cbc fix logic bug in check_index_scan() that swapped lhs/rhs but not the comparison op 2025-01-08 08:20:13 +02:00
Jussi Saurio
4a58898863 Rename eliminate_between to rewrite_exprs and add true/false->1/0 case there 2025-01-08 08:20:13 +02:00
Jussi Saurio
1b61749c0f feat/core/translate: create automatic index in CREATE TABLE when necessary 2025-01-04 13:54:44 +02:00
Jussi Saurio
80b9da95c0 replace termination_label_stack with much simpler LoopLabels 2025-01-01 07:56:39 +02:00
Jussi Saurio
2066475e03 feat: subqueries in FROM clause 2024-12-31 14:18:29 +02:00
Lauri Virtanen
854005b977 Run cargo clippy --fix && cargo fmt 2024-12-29 19:22:28 +02:00
PThorpe92
f6cd707544 Add clippy CI, fix or ignore warnings where appropriate 2024-12-29 10:25:41 -05:00
adamnemecek
97647ff056 Clean up code to use Self
Closes #556
2024-12-29 10:07:38 +02:00
김선우
5cdcb8d78c Split Plan into Select and Delete 2024-12-23 05:45:23 +09:00
김선우
82c127b7a3 Remove bool args in optimize_plan 2024-12-23 04:47:05 +09:00