We were incorrectly setting `moved_before` as `false` after checking
for unique constraint violation, but the reality is that after the
uniqueness check, we are already correctly positioned -- if no match
was found, the cursor is positioned at either:
a) no row, or
b) at the first entry that is greater than the key we are inserting.
This means we don't have to move anymore and can just insert.
Adds an `#[instrument]` to many btree related functions. Also, when
debugging #1717 it would be impossible to debug as the 10Mb SeekKey
would be printed to my terminal making the experience miserable. The
debug implementation now truncates the Blobs and Strings when they are
too big to be useful.
Closes#1721
This PR implements SQLite-compatible affinity-based type coercion for
seek operations and comparison operators, bringing Limbo's behavior
closer to SQLite's type conversion rules.
### Key Changes
- Added affinity handling to all comparison operators (`Eq`, `Ne`, `Lt`,
`Le`, `Gt`, `Ge`).
- Added `get_expr_affinity()` to determine expression affinity based on
column types and casts.
- Added affinity functionality `CmpInsFlags` which carries the affinity
information from translation layer to execution layer.
- Added comprehensive `apply_numeric_affinity()` function that handles
many edge cases when converting to numerical quantities.
- Implemented `comparison_affinity()` that follows SQLite's affinity
precedence rules.
- Added fuzz tests for partial numeric strings, hex literals, and
various numeric formats.
### SQLite Compatibility Improvements
This implementation now correctly handles cases like:
- `SELECT * FROM t WHERE x < X'41'` (blob comparisons)
- `SELECT * FROM t WHERE x < '123abc'` (partial numeric strings)
- `SELECT * FROM t WHERE x < 4.9 ` (float precision in seeks)
- Mixed-type comparisons with proper affinity conversion
Thanks 🤝@PThorpe92 and @pedrocarlo for helping improve my planner
understanding.
Closes: https://github.com/tursodatabase/limbo/issues/1607Closes#1680
- Entire stdout+stderr was passed to both title and body for the github
issue, resulting in a failure due to github's validation
Fixes:
- Pass only the line containing "simulation failed:" as title
- Pass max 50 lines following title as body
- Truncate title and body to 255 and 65536 chars respectively before
posting github issue, just to be sure
Closes#1711
This PR attempts to get the specific query that failed in the simulator
and get the correct tables that were used in the Query. Also, implements
a fix where after clearing miscellaneous queries, we did not check again
if the the interaction still referenced any of the tables that were
involved in the failure.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1712
Adds a Sqlite integrity check after the simulator completes a run. Also
changed error handling in the simulator to use `anyhow` to lazily add
context to error methods instead of eagerly using `.or` and losing the
original error.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1697
- Entire stdout+stderr was passed to both title and body for the github
issue, resulting in a failure due to github's validation
Fixes:
- Pass only the line containing "simulation failed:" as title
- Pass max 50 lines following title as body
- Truncate title and body to 255 and 65536 chars respectively
before posting github issue, just to be sure
to integer. Exising functions' behavior is tailored to `CAST` ops.
SQLite has different behavior when it comes to handling string to
`integer` conversion in CAST vs predicate ops.
This PR adds column names to the ouput of js pragma function.
Reviewed-by: Diego Reis (@el-yawd)
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#1608
Due to the left-prefix rule of indexes, for an index key to be usable,
it needs to:
- Use the columns in contiguous order (0, 1, 2...)
* eg if WHERE refers to cols 0 and 2, only 0 can be used
- Stop at the first range operator
* eg if WHERE: col1 = 5 AND col2 > 5 AND col3 = 5, only col1 and col2
can be used.
This wasn't properly tested, and resulted in simulator failures (e.g.
seed `10818913476224476676` which no longer fails with this fix). Added
some regression tests for this behavior, as well.
Reviewed-by: Preston Thorpe (@PThorpe92)
Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Closes#1698
Due to the left-prefix rule of indexes, for an index key to be usable,
it needs to:
- Use the columns in contiguous order (0, 1, 2...)
* eg if WHERE refers to cols 0 and 2, only 0 can be used
- Stop at the first range operator
* eg if WHERE: col1 = 5 AND col2 > 5 AND col3 = 5, only col1 and col2
can be used.
This wasn't properly tested, and resulted in simulator failures. Added
some regression tests for this behavior.
The major change in this PR is the following:
- It refactors deserializing the record from the cell so that it does
not happen in `next()` or `prev()`, but lazily when it is needed. This
will allow a further enhancement where we only read a _partial_ section
of the record payload, e.g. when `Insn::Column` is requested by the
VDBE, we can only deserialize the relevant column.
It also fixes multiple bugs in `BTreeCursor`
Follow-ups:
ASAP: fix performance regression (probably due to too much record
invalidation)
ASAP: do post-balance seek key calculation only when balance will be
needed
ASAP: fix balancing scenario where interior index cell is deleted - even
if leaf doesnt require balance, parent might. both need to be checked
LATER: implement safe way to use indexes for UPDATE -- ephemeral indexes
needed, see FIXME in `optimizer/mod.rs`
LATER: implement on-demand serialization of parts of the record, instead
of entire record
Closes#1664