Jussi Saurio
12a2c2b9ad
Add more documentation to OPTIMIZER.MD
2025-05-14 09:42:26 +03:00
Jussi Saurio
fe628e221a
plan_satisfies_order_target(): simplify
2025-05-14 09:42:26 +03:00
Jussi Saurio
4dde356d97
AccessMethod: simplify
2025-05-14 09:42:26 +03:00
Jussi Saurio
a90358f669
TableMask: comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
f12eb25962
cost.rs: simplify cost estimation
2025-05-14 09:42:26 +03:00
Jussi Saurio
4f07c808b2
Fix bug with constraint ordering introduced by refactor
2025-05-14 09:42:26 +03:00
Jussi Saurio
52b28d3099
rename use_indexes to optimize_table_access
2025-05-14 09:42:26 +03:00
Jussi Saurio
d8218483a2
use_indexes: comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
e53ab385d7
order.rs: comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
ff8e187eda
find_best_access_method_for_join_order: comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
3442e4981d
remove some unnecessary parameters
2025-05-14 09:42:26 +03:00
Jussi Saurio
c18bb3cd14
rename
2025-05-14 09:42:26 +03:00
Jussi Saurio
15b32f7e57
constraints.rs: more comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
c782616180
Refactor constraints so that WHERE clause is not needed in join reordering phase
2025-05-14 09:42:26 +03:00
Jussi Saurio
6aa5b01a7b
Add note about optimizer directory structure
2025-05-14 09:42:26 +03:00
Jussi Saurio
bd875e3876
optimizer module split
2025-05-14 09:42:26 +03:00
Jussi Saurio
ec45a92bac
move optimizer to its own directory
2025-05-14 09:42:26 +03:00
Jussi Saurio
c639a43676
fix parenthesized column edge case
2025-05-14 09:42:26 +03:00
Jussi Saurio
90de8791f5
comments
2025-05-14 09:42:26 +03:00
Jussi Saurio
c8f5bd3f4f
rename
2025-05-14 09:42:26 +03:00
Jussi Saurio
630a6093aa
refactor join_lhs_tables_to_rhs_table
2025-05-14 09:42:26 +03:00
Jussi Saurio
62d2ee8eb6
rename
2025-05-14 09:42:26 +03:00
Jussi Saurio
5f9ebe26a0
as_binary_components() helper
2025-05-14 09:42:26 +03:00
Jussi Saurio
a92d94270a
Get rid of useless ScanCost struct
2025-05-14 09:42:26 +03:00
Jussi Saurio
de9e8442e8
fix ephemeral
2025-05-14 09:42:25 +03:00
Jussi Saurio
3b1aef4a9e
Do Less Work (tm) - everything works except ephemeral
2025-05-14 09:42:01 +03:00
Jussi Saurio
87850e5706
simplify
2025-05-14 09:41:14 +03:00
Jussi Saurio
77f11ba004
simplify AccessMethodKind
2025-05-14 09:41:14 +03:00
Jussi Saurio
5f724d6b2e
Add more comments to join ordering logic
2025-05-14 09:41:14 +03:00
Jussi Saurio
c02d3f8bcd
Do groupby/orderby sort elimination based on optimizer decision
2025-05-14 09:41:13 +03:00
Jussi Saurio
1e46f1d9de
Feature: join reordering optimizer
2025-05-14 09:40:48 +03:00
Jussi Saurio
c8c83fc6e6
OPTIMIZER.MD docs
2025-05-14 09:39:47 +03:00
Jussi Saurio
67a080bfa0
dont mutate where clause during individual index selection phase
2025-05-14 09:39:47 +03:00
Jussi Saurio
1b71f58bbf
Merge 'Redesign parameter binding in query translator' from Preston Thorpe
...
closes #1467
## Example:
Previously as explained in #1449 , our parameter binding wasn't working
properly because we would essentially
assign the first index of whatever was translated first
```console
limbo> create table t (id integer primary key, name text, age integer);
limbo> explain select * from t where name = ? and id > ? and age between ? and ?;
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 20 0 0 Start at 20
1 OpenRead 0 2 0 0 table=t, root=2
2 Variable 1 4 0 0 r[4]=parameter(1) # always 1
3 IsNull 4 19 0 0 if (r[4]==NULL) goto 19
4 SeekGT 0 19 4 0 key=[4..4]
5 Column 0 1 5 0 r[5]=t.name
6 Variable 2 6 0 0 r[6]=parameter(2) # always 2
7 Ne 5 6 18 0 if r[5]!=r[6] goto 18
8 Variable 3 7 0 0 r[7]=parameter(3) # etc...
9 Column 0 2 8 0 r[8]=t.age
10 Gt 7 8 18 0 if r[7]>r[8] goto 18
11 Column 0 2 9 0 r[9]=t.age
12 Variable 4 10 0 0 r[10]=parameter(4)
13 Gt 9 10 18 0 if r[9]>r[10] goto 18
14 RowId 0 1 0 0 r[1]=t.rowid
15 Column 0 1 2 0 r[2]=t.name
16 Column 0 2 3 0 r[3]=t.age
17 ResultRow 1 3 0 0 output=r[1..3]
18 Next 0 5 0 0
19 Halt 0 0 0 0
20 Transaction 0 0 0 0 write=false
21 Goto 0 1 0 0
```
## Solution:
`rewrite_expr` currently is used to transform `true|false` to `1|0`, so
it has been adapted to transform anonymous `Expr::Variable`s to named
variables, inserting the appropriate index of the parameter by passing
in a counter.
```rust
ast::Expr::Variable(var) => {
if var.is_empty() {
// rewrite anonymous variables only, ensure that the `param_idx` starts at 1 and
// all the expressions are rewritten in the order they come in the statement
*expr = ast::Expr::Variable(format!("{}{param_idx}", PARAM_PREFIX));
*param_idx += 1;
}
Ok(())
}
```
# Corrected output: (notice the seek)
```console
limbo> explain select * from t where name = ? and id > ? and age between ? and ?;
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 20 0 0 Start at 20
1 OpenRead 0 2 0 0 table=t, root=2
2 Variable 2 4 0 0 r[4]=parameter(2)
3 IsNull 4 19 0 0 if (r[4]==NULL) goto 19
4 SeekGT 0 19 4 0 key=[4..4]
5 Column 0 1 5 0 r[5]=t.name
6 Variable 1 6 0 0 r[6]=parameter(1)
7 Ne 5 6 18 0 if r[5]!=r[6] goto 18
8 Variable 3 7 0 0 r[7]=parameter(3)
9 Column 0 2 8 0 r[8]=t.age
10 Gt 7 8 18 0 if r[7]>r[8] goto 18
11 Column 0 2 9 0 r[9]=t.age
12 Variable 4 10 0 0 r[10]=parameter(4)
13 Gt 9 10 18 0 if r[9]>r[10] goto 18
14 RowId 0 1 0 0 r[1]=t.rowid
15 Column 0 1 2 0 r[2]=t.name
16 Column 0 2 3 0 r[3]=t.age
17 ResultRow 1 3 0 0 output=r[1..3]
18 Next 0 5 0 0
19 Halt 0 0 0 0
20 Transaction 0 0 0 0 write=false
21 Goto 0 1 0 0
```
## And a `Delete`:
```console
limbo> explain delete from t where name = ? and age > ? and id > ?;
addr opcode p1 p2 p3 p4 p5 comment
---- ----------------- ---- ---- ---- ------------- -- -------
0 Init 0 15 0 0 Start at 15
1 OpenWrite 0 2 0 0
2 Variable 3 1 0 0 r[1]=parameter(3)
3 IsNull 1 14 0 0 if (r[1]==NULL) goto 14
4 SeekGT 0 14 1 0 key=[1..1]
5 Column 0 1 2 0 r[2]=t.name
6 Variable 1 3 0 0 r[3]=parameter(1)
7 Ne 2 3 13 0 if r[2]!=r[3] goto 13
8 Column 0 2 4 0 r[4]=t.age
9 Variable 2 5 0 0 r[5]=parameter(2)
10 Le 4 5 13 0 if r[4]<=r[5] goto 13
11 RowId 0 6 0 0 r[6]=t.rowid
12 Delete 0 0 0 0
13 Next 0 5 0 0
14 Halt 0 0 0 0
15 Transaction 0 1 0 0 write=true
16 Goto 0 1 0 0
```
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com >
Closes #1475
2025-05-14 09:26:06 +03:00
Jussi Saurio
a0f973cb34
Merge 'Fix infinite loop when inserting multiple rows' from Jussi Saurio
...
Due to constant instruction reshuffling introduced in #1359 , it is
advisable not to do either of the following:
1. Use raw offsets as jump targets
2. Use `program.resolve_label(my_label, program.offset())` when it is
uncertain what the next instruction will be
Instead, if you want a label to point to "whatever instruction follows
the last one", you should use
`program.preassign_label_to_next_insn(label)`, which will work correctly
even with instruction rerdering
Reviewed-by: Preston Thorpe (@PThorpe92)
Closes #1474
2025-05-14 09:24:47 +03:00
Pekka Enberg
bef665b7f3
Limbo 0.0.20-pre.2
2025-05-14 09:17:07 +03:00
Pekka Enberg
d912f14528
Update CHANGELOG
2025-05-14 09:16:53 +03:00
Pekka Enberg
67775fbc1d
Merge 'github: Ensure rustmft is installed' from Pekka Enberg
...
Closes #1478
2025-05-14 09:16:10 +03:00
Pekka Enberg
da3815e1cb
github: Ensure rustmft is installed
2025-05-14 09:12:35 +03:00
Pekka Enberg
3be9807e4f
Update CHANGELOG
2025-05-14 08:58:08 +03:00
PThorpe92
a0b2b6e85d
Consolidate match case in parameters push to handle all anonymous params in one case
2025-05-13 14:42:12 -04:00
PThorpe92
2f255524bd
Remove unused import and unnecessary mut annotations in insert.rs
2025-05-13 14:34:22 -04:00
PThorpe92
94aa9cd99d
Add cases to rewrite_expr in the optimizer
2025-05-13 14:33:45 -04:00
PThorpe92
16ac6ab918
Fix parameter push method to re-convert anonymous parameters
2025-05-13 14:33:11 -04:00
PThorpe92
e91d17f06e
Add tests for parameter binding for update, select and delete queries
2025-05-13 12:50:10 -04:00
PThorpe92
0593a99f0e
Remove insertCtx from parameters and replace fix with expr rewriting
2025-05-13 12:49:16 -04:00
Jussi Saurio
3cc9147f6c
Merge 'testing/py: rename debug_print() to run_debug()' from Jussi Saurio
...
I wasted a few minutes staring at #1471 because I thought
`limbo.debug_print()` just prints the sql, but it actually executes it
too
Reviewed-by: Preston Thorpe (@PThorpe92)
Closes #1472
2025-05-13 10:12:27 +03:00
Jussi Saurio
a2e577ad01
Merge 'Fix handling of empty strings in prepared statements' from Diego Reis
...
When `prepare()` is called with an empty string it should throw an error
(e.g `ApiMisuse` in rusqlite). I'm testing only in JS but it should
throw to any bind.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com >
Closes #1473
2025-05-13 10:12:09 +03:00
Jussi Saurio
44e282f630
Add multi-row insert regression test
2025-05-13 09:03:01 +03:00
Jussi Saurio
957fe1b446
Fix infinite loop when inserting multiple rows
2025-05-13 08:54:25 +03:00