Fix IdxGt,IdxGe,IdxLt,IdxLe instructions

According to SQLite documentation, the way to use these instructions
is to compare the seek key to the index key as you would with the
Compare opcode. The compare opcode states:

"Compare two vectors of registers in reg(P1)..reg(P1+P3-1)
(call this vector "A") and in reg(P2)..reg(P2+P3-1) ("B")."

In other words, we should compare the same number of columns from each,
not compare the entire keys.

This fixes a few Clickbench queries returning incorrect results, and
so closes #1009

---

Future work: support index seek keys that use multiple columns. Our
index seek is many times slower than SQLite because we're not utilizing
all the possible columns -- instead we just use the first index column
to seek.
This commit is contained in:
Jussi Saurio
2025-02-15 12:44:56 +02:00
parent f220f9a948
commit e4541edb48

View File

@@ -1399,8 +1399,8 @@ impl Program {
let record_from_regs: Record =
make_owned_record(&state.registers, start_reg, num_regs);
if let Some(ref idx_record) = *cursor.record()? {
// omit the rowid from the idx_record, which is the last value
if idx_record.get_values()[..idx_record.len() - 1]
// Compare against the same number of values
if idx_record.get_values()[..record_from_regs.len()]
>= record_from_regs.get_values()[..]
{
state.pc = target_pc.to_offset_int();
@@ -1423,8 +1423,8 @@ impl Program {
let record_from_regs: Record =
make_owned_record(&state.registers, start_reg, num_regs);
if let Some(ref idx_record) = *cursor.record()? {
// omit the rowid from the idx_record, which is the last value
if idx_record.get_values()[..idx_record.len() - 1]
// Compare against the same number of values
if idx_record.get_values()[..record_from_regs.len()]
<= record_from_regs.get_values()[..]
{
state.pc = target_pc.to_offset_int();
@@ -1447,8 +1447,8 @@ impl Program {
let record_from_regs: Record =
make_owned_record(&state.registers, start_reg, num_regs);
if let Some(ref idx_record) = *cursor.record()? {
// omit the rowid from the idx_record, which is the last value
if idx_record.get_values()[..idx_record.len() - 1]
// Compare against the same number of values
if idx_record.get_values()[..record_from_regs.len()]
> record_from_regs.get_values()[..]
{
state.pc = target_pc.to_offset_int();
@@ -1471,8 +1471,8 @@ impl Program {
let record_from_regs: Record =
make_owned_record(&state.registers, start_reg, num_regs);
if let Some(ref idx_record) = *cursor.record()? {
// omit the rowid from the idx_record, which is the last value
if idx_record.get_values()[..idx_record.len() - 1]
// Compare against the same number of values
if idx_record.get_values()[..record_from_regs.len()]
< record_from_regs.get_values()[..]
{
state.pc = target_pc.to_offset_int();