Commit Graph

53 Commits

Author SHA1 Message Date
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
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
ae88d51e6f Remove TableReferenceType enum to clean up planner 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
40f536fabb Dont store available_indexes on plan; only used in optimize_plan() 2025-02-03 12:52:14 +02: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
e63256f657 Change Display implementation of Plan to work with new data structures 2025-02-02 10:18:13 +02:00
Jussi Saurio
390d0e673f plan.rs: refactor data structures
- Get rid of SourceOperator tree
- Make plan have a Vec of TableReference, and TableReference now
  contains the information from the old SourceOperator.
- Remove `predicates` (conditions) from Table References -- put
  everything in the WHERE clause like SQLite, and attach metadata
  to the where clause expressions with JoinAwareConditionExpr struct.
- Refactor select_star() to be simpler now that we use a vec, not a tree
2025-02-02 10:18:13 +02:00
Glauber Costa
249a8cf8d2 keep type information as a string in column metadata
SQLite holds on to it deeply, for example:

sqlite> create table a(a int);
sqlite> create table b(b integer);
sqlite> create table c(c glauber);

sqlite> pragma table_info=a;
0|a|INT|0||0
sqlite> pragma table_info=b;
0|b|INTEGER|0||0
sqlite> pragma table_info=c;
0|c|glauber|0||0

So we'll keep it as well so we can produce the same responses.
2025-01-30 19:53:36 -05:00
Glauber Costa
69d3fbc797 keep track of notnull constraint on column creation 2025-01-30 17:04:12 -05:00
Glauber Costa
42f93e9bea add default type to Column definition 2025-01-30 16:45:57 -05:00
ben594
54a6505b33 Handle negative limits and offsets 2025-01-26 16:40:30 -05:00
ben594
d03a0dbd39 Added parsing of offset clause 2025-01-26 16:40:30 -05:00
Jorge López
86a4714711 syntactic changes: remove unneeded paths when the type is already imported 2025-01-18 18:29:12 +01:00
Jussi Saurio
9909539b9d Store cursor type (table,index,pseudo,sorter) when allocating cursor 2025-01-11 17:04:16 +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
PThorpe92
f6cd707544 Add clippy CI, fix or ignore warnings where appropriate 2024-12-29 10:25:41 -05:00
Pekka Enberg
3bc554f27c core: Remove unused import 2024-12-27 18:39:38 +02:00
김선우
5cdcb8d78c Split Plan into Select and Delete 2024-12-23 05:45:23 +09:00
Pekka Enberg
61269e9c03 Merge 'Fix primary key handling' from Jussi Saurio
Closes #438
**Fixes:**
- Return the actual primary key instead of the rowid when the primary
key is not a rowid alias
sqlite:
```
limbo> create table foo (pk TEXT PRIMARY KEY, value);
sqlite> insert into foo values ('one', 'payload');
sqlite> insert into foo values ('two', 'payload');
sqlite> select * from foo;
one|payload
two|payload
```
limbo now:
```
limbo> create table foo (pk TEXT PRIMARY KEY, value);
limbo> insert into foo values ('one', 'payload');
limbo> insert into foo values ('two', 'payload');
limbo> select * from foo;
one|payload
two|payload
```
limbo before:
```
limbo> select * from foo;
1|payload
2|payload
```
Then, discovered two issues when running the whole TCL test suite
against a copy of `testing.db` that does not have rowid aliases in the
tables:
- Fix trying to convert a Scan into an IndexSearch when the associated
Expr refers to a different instance of the same table in a self-join
- Fix `scan_loop_body_labels` being pushed to in different parts of the
codegen for Scan/Search nodes resulting in incorrect label resolutions
**Additions:**
- Add a new db `testing/testing_norowidalias.db` that is a carbon copy
of `testing/testing.db` except the `id` columns of `users` and
`products` are not rowid aliases (i.e. they are `INT PRIMARY KEY`
instead of `INTEGER PRIMARY KEY`
- Run all TCL tests against both test databases with `do_execsql_test`
```
(testing/testing.db)                        Running test: coalesce-from-table
(testing/testing_norowidalias.db)           Running test: coalesce-from-table
(testing/testing.db)                        Running test: coalesce-from-table-column
(testing/testing_norowidalias.db)           Running test: coalesce-from-table-column
(testing/testing.db)                        Running test: coalesce-from-table-multiple-columns
(testing/testing_norowidalias.db)           Running test: coalesce-from-table-multiple-columns
(testing/testing.db)                        Running test: glob-fn
(testing/testing_norowidalias.db)           Running test: glob-fn
(testing/testing.db)                        Running test: where-glob
(testing/testing_norowidalias.db)           Running test: where-glob
(testing/testing.db)                        Running test: where-glob-question-mark
(testing/testing_norowidalias.db)           Running test: where-glob-question-mark
```
- Allow running tests against specific db file with
`do_execsql_test_on_specific_db $path`
- Wondering if I should add a new table with e.g. text primary key and
add some db-specific tests on that table...?

Closes #449
2024-12-16 18:49:19 +02:00
jussisaurio
419ccc327e Dont assume GROUP BY has aggregates 2024-12-16 00:30:38 +02:00
jussisaurio
961e57df94 Fix returning rowid instead of PK when PK is not a rowid alias 2024-12-14 15:51:08 +02:00
jussisaurio
5e9e2dffe9 support TRUE and FALSE in predicates 2024-12-13 22:58:29 +02:00
jussisaurio
840caed2f7 Fix bug with multiway joins that include the same table multiple times 2024-12-09 17:50:29 +02:00
jussisaurio
bed932c186 Support join USING 2024-12-09 17:50:29 +02:00
jussisaurio
3f80e41e7a support HAVING 2024-11-30 10:05:13 +02:00
jussisaurio
84742b81fa Obsolete comment 2024-11-27 22:43:36 +02:00
jussisaurio
da811dc403 add doc comments for members of Plan struct 2024-11-27 19:30:07 +02:00
jussisaurio
ac12e9c7fd No need for ResultSetColumn to be an enum 2024-11-26 17:31:51 +02:00
jussisaurio
7ecc252507 fix rest of the failing tests 2024-11-26 17:31:51 +02:00
jussisaurio
9a557516b8 Fixes for expressions with aggregate arguments + limit 0 2024-11-26 17:31:51 +02:00
jussisaurio
3f9e60633f select refactor: order by and basic agg kinda work 2024-11-26 17:31:51 +02:00
jussisaurio
d0466e1cae introduce Column member of ast::Expr and bind idents to columns 2024-11-26 17:31:51 +02:00
limeng.1
5e9e701417 resolve comments 2024-11-19 11:39:08 +08:00
limeng.1
1cb1d16c08 resolve comments 2024-11-19 11:39:08 +08:00
limeng.1
8cca659052 impl order by desc 2024-11-19 11:39:07 +08:00
jussisaurio
b3c57d5691 core/translate: (refactor) use btreetablereference struct instead of tuple 2024-10-13 11:25:33 +03:00
jussisaurio
bb1c8b65e8 fmt 2024-10-06 00:22:12 +03:00
jussisaurio
dde10d2dd7 Better EXPLAIN QUERY PLAN for Operator::Search 2024-10-06 00:19:56 +03:00
jussisaurio
47534cb8df Get rid of Seekrowid operator in favor of a unified Search operator 2024-10-06 00:11:38 +03:00
jussisaurio
3d56fbd91c stuff 2024-10-05 18:25:04 +03:00
jussisaurio
f02da18acd index scan wip foo doesnt work yet 2024-10-05 18:25:04 +03:00
jussisaurio
a108dea825 GROUP BY 2024-09-14 16:14:45 +03:00
jussisaurio
d1059da9f1 Return enum instead of bool for better documentation 2024-08-25 11:15:47 +03:00
Piotr Sarna
d8002ff03c core: pretty-print EXPLAIN QUERY PLAN
Mimics SQLite's EXPLAIN QUERY PLAN pretty printer.

Example run on a preexisting db:
```
$ cargo run /tmp/srn "explain query plan select * from t natural join t join t2 on t.id = 2*t2.id where t.id in (select * from t);"
QUERY PLAN
`--JOIN ON t.id = 2 * t2.id
   |--JOIN
   |  |--SCAN t FILTER t.id IN (SELECT * FROM t)
   |  `--SCAN t
   `--SCAN t2

```

Fixes https://github.com/penberg/limbo/issues/295
2024-08-18 20:11:19 +02:00
jussisaurio
e8c894e532 More flexible Emitter via stateful operators 2024-08-17 12:55:16 +03:00
jussisaurio
069826820e Finish renaming node -> operator 2024-08-16 19:42:03 +03:00
jussisaurio
97dc98336c fix comment 2024-08-16 19:42:03 +03:00