Commit Graph

326 Commits

Author SHA1 Message Date
Jussi Saurio
4e6f373e3d Merge 'Fix: Evaluating expression in LIMIT and OFFSET clauses.' from
Closes #3687 .
Previously, the `try_fold_expr_to_i64` function casted `NULL` as `0`
when evaluating expressions in `LIMIT` or `OFFSET` clauses. I removed
this function since evaluating the expression directly and relying on
the MustBeInt operation for casting seems to handle everything.

Closes #3695
2025-10-15 10:36:36 +03:00
Jussi Saurio
bae33cb52c Avoid unwrapping failed f64 parsing attempts 2025-10-15 09:47:47 +03:00
Jussi Saurio
87434b8a72 Do not count DELETEs occuring in an UPDATE stmt as separate changes 2025-10-14 16:11:43 +03:00
Jussi Saurio
f5ee4807da Properly differentiate between source and target in UPDATE
- Encode information about ephemeral source table in OperationMode::UPDATE
  if present
- Use OperationMode information to correctly resolve cursors in UPDATE
2025-10-14 14:17:28 +03:00
rajajisai
cd763ce373 Fix evalauting expression for limit and offset. 2025-10-12 22:46:25 -04:00
PThorpe92
7e9277958b Fix deferred FK in vdbe 2025-10-07 16:45:23 -04:00
PThorpe92
a232e3cc7a Implement proper handling of deferred foreign keys 2025-10-07 16:45:23 -04:00
PThorpe92
f56f37fae5 Add more tests for self-referencing FKs and remove unneeded FkIfZero checks/labels in emitter 2025-10-07 16:45:23 -04:00
PThorpe92
fa23cedbbe Add helper to pragma to parse enabled opts and fix schema parsing for foreign key constraints 2025-10-07 16:45:22 -04:00
PThorpe92
37c8abf247 Fix schema representation and methods for ForeignKey resolution 2025-10-07 16:45:22 -04:00
Jussi Saurio
5a5f49933d Collate: add proper collation info to DISTINCT indexes 2025-10-02 21:49:33 +03:00
Mikaël Francoeur
dc231abb2e fix self-insert bug 2025-09-29 17:18:19 -04:00
Preston Thorpe
da599a1fb8 Merge 'quoting fix' from Nikita Sivukhin
This PR moves part of string normalization to the parser layer.
Now, we dequote and unescape values in the parser, but we still need to
lowercase them for proper ignore-case comparison logic in the planner.
The reason to not lowercase in the parser is following:
1. SQLite (and tursodb) have ident->string conversion rule and by
lowercasing value early we will loose original representation
2. Some things like column names are preserve the case right now and we
better to not change this behaviour.

Closes #3344
2025-09-29 12:33:42 -04:00
Nikita Sivukhin
0910483522 fix clippy 2025-09-29 16:30:07 +04:00
Nikita Sivukhin
12863b35c4 fix compound select 2025-09-29 16:21:35 +04:00
Nikita Sivukhin
49a5617a95 fix limit for compount select 2025-09-29 15:51:39 +04:00
Nikita Sivukhin
70e18ce3f7 validate zero limit at the beginning in the VDBE program
- before, we validated that condition during program emit - which works for fixed values of parameters but doesn't work with variables provided externally to the prepared statement
2025-09-29 15:32:36 +04:00
Nikita Sivukhin
86a95e813d Merge branch 'main' into quoting-fix-attempt-2 2025-09-29 10:58:51 +04:00
PThorpe92
5fcc187434 translate: refactor arguments and centralize parameter context 2025-09-26 12:06:44 -04:00
Nikita Sivukhin
2f4d76ec6d remove pattern matching over Name::Quoted 2025-09-26 13:01:49 +04:00
PThorpe92
3a5b9dcf35 Fix UPDATE behavior to handle explicit rowid update on non rowid alias columns 2025-09-25 19:16:00 -04:00
Jussi Saurio
726bc24e78 Support referring to rowid as _rowid_ or oid 2025-09-24 09:17:28 +03:00
Jussi Saurio
d5de088abe Merge 'translate: implement Sequence opcode and fix sort order' from Preston Thorpe
This PR implements the `Sequence` and `SequenceTest` opcodes, although
does not yet add plumbing to emit the latter.
SQLite has two distinct mechanisms that determine the final row order
with aggregates:
Traversal order of GROUP BY, and ORDER BY tiebreaking. When ORDER BY
contains only aggregate expressions and/or constants, SQLite has no
extra tiebreak key, but when ORDER BY mixes aggregate and non-aggregate
terms, SQLite adds an implicit, stable row `sequence` so “ties” respect
the input order.
This PR also fixes an issue with a query like the following:
```sql
SELECT u.first_name, COUNT(*) AS c
FROM users u
JOIN orders o ON o.user_id = u.id
GROUP BY u.first_name
ORDER BY c DESC;
```
Because ORDER BY has only an aggregate (COUNT(*) DESC) and no non-
aggregate terms, SQLite traverses the group key (u.first_name) in DESC
order in this case, so ties on c naturally appear with group keys in
descending order.
Previously tursodb would return the group key sorted in ASC order,
because it was used in all cases as the default

Closes #3287
2025-09-24 08:38:08 +03:00
PThorpe92
376d2bf7b1 Add plumbing to add sequence column to stabilize tiebreakers in order+group by 2025-09-23 22:35:59 -04:00
PThorpe92
e545e75e31 Emit Affinity instruction for unique index, and use no_constant_opt 2025-09-21 13:24:48 -04:00
PThorpe92
03149bc92d Remove unused imports 2025-09-20 18:32:37 -04:00
PThorpe92
93d24d2b50 Use new bind_where_expr helper method in emitter 2025-09-20 17:43:50 -04:00
PThorpe92
340b95aa8b Apply PR review suggestions, add comments to partial indexes 2025-09-20 14:38:50 -04:00
PThorpe92
21f6455190 Fix clippy warnings and tests 2025-09-20 14:38:50 -04:00
PThorpe92
f4258b8b08 Just use raw pointer instead of cloning JoinedTable in emitter 2025-09-20 14:38:49 -04:00
PThorpe92
6d8bf009f1 Add some comments 2025-09-20 14:38:49 -04:00
PThorpe92
51f970a263 Support partial indexes in INSERT/UPDATE/DELETE 2025-09-20 14:38:48 -04:00
Jussi Saurio
cae234818b Merge 'Inital support for window functions' from Piotr Rżysko
This adds basic support for window functions. For now:
* Only existing aggregate functions can be used as window functions.
* Specialized window-specific functions (`rank`, `row_number`, etc.) are
not yet supported.
* Only the default frame definition is implemented:
`RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS`.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #3079
2025-09-17 08:29:16 +03:00
Jussi Saurio
396091044e store tx_mode in conn.mv_tx
otherwise op_transaction works completely wrong because each separate
insert statement overrides the tx_mode to Write
2025-09-14 21:59:08 +03:00
Piotr Rzysko
f5efcbe745 Add support for window functions
Adds initial support for window functions. For now, only existing
aggregate functions can be used as window functions—no specialized
window-specific functions are supported yet.

Currently, only the default frame definition is implemented:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS.
2025-09-13 11:12:44 +02:00
Pekka Enberg
433b60555f Add BEGIN CONCURRENT support for MVCC mode
Currently, when MVCC is enabled, every transaction mode supports
concurrent reads and writes, which makes it hard to adopt for existing
applications that use `BEGIN DEFERRED` or `BEGIN IMMEDIATE`.

Therefore, add support for `BEGIN CONCURRENT` transactions when MVCC is
enabled. The transaction mode allows multiple concurrent read/write
transactions that don't block each other, with conflicts resolved at
commit time. Furthermore, implement the correct semantics for `BEGIN
DEFERRED` and `BEGIN IMMEDIATE` by taking advantage of the pager level
write lock when transaction upgrades to write. This means that now
concurrent MVCC transactions are serialized against the legacy ones when
needed.

The implementation includes:

- Parser support for CONCURRENT keyword in BEGIN statements

- New Concurrent variant in TransactionMode to distinguish from regular
  read/write transactions

- MVCC store tracking of exclusive transactions to support IMMEDIATE and
  EXCLUSIVE modes alongside CONCURRENT

- Proper transaction state management for all transaction types in MVCC

This enables better concurrency for applications that can handle
optimistic concurrency control, while still supporting traditional
SQLite transaction semantics via IMMEDIATE and EXCLUSIVE modes.
2025-09-11 16:05:52 +03:00
Jussi Saurio
6d43bdbf71 emit the Delete instruction for the iteration index cursor, and do it last 2025-09-10 14:54:51 +03:00
Pekka Enberg
f88f39082a core/vdbe: Fix MakeRecord affinity handling
The MakeRecord instruction now accepts an optional affinity_str
parameter that applies column-specific type conversions before creating
records. When provided, the affinity string is applied
character-by-character to each register using the existing
apply_affinity_char() function, matching SQLite's behavior.

Fixes #2040
Fixes #2041
2025-09-08 18:49:13 +03:00
bit-aloo
05267454dc remove redundant step during limit/offset evaluation and add test coverage most of the datatypes and some expression 2025-08-26 19:56:25 +05:30
bit-aloo
a3b87cd97f add review comments 2025-08-26 19:56:25 +05:30
bit-aloo
50d9b0f7e3 ignore limit for value less than 9 2025-08-26 19:56:25 +05:30
bit-aloo
a16bee4574 move to new parser 2025-08-26 19:56:24 +05:30
bit-aloo
1e5275682d make early exit for value less than equal zero 2025-08-26 19:56:12 +05:30
bit-aloo
ffcadd00ae evaluate limit or offset expr 2025-08-26 19:56:12 +05:30
Levy A.
4ba1304fb9 complete parser integration 2025-08-21 15:23:59 -03:00
Levy A.
186e2f5d8e switch to new parser 2025-08-21 15:19:16 -03:00
Jussi Saurio
dd2e0ea596 Fix: always emit rowid when column is rowid alias
SQLite does not store the rowid alias column in the record at all
when it is a rowid alias, because the rowid is always stored anyway
in the record header.
2025-08-21 16:40:10 +03:00
Jussi Saurio
f9ad43a3a3 Merge 'Fix: all indexes need to be updated if the rowid changes' from Jussi Saurio
Found when running simulator in #2641
All indexes store the rowid as the last column, so whenever the rowid of
a given row changes the index entry must also be deleted and reinserted
with the new index.

Reviewed-by: Nikita Sivukhin (@sivukhin)

Closes #2712
2025-08-21 16:40:03 +03:00
Jussi Saurio
e224bb15a8 Fix incorrect UNIQUE constraint failure behavior in UPDATE
UPDATE should skip over the UNIQUE constraint failure if the existing
row it found during the check has the same rowid as the row we are
currently updating
2025-08-21 16:30:34 +03:00
Jussi Saurio
6c0c4d77d0 Fix UPDATE inserting NULL into index instead of rowid 2025-08-21 14:58:25 +03:00