Fix DecrJumpZero usage in translate_select()

SQLite special-cases `LIMIT 0` by emitting an explicit `Goto` to avoid
executing any `ResultRow` statements. We, however, hacked around this in
DecrJumpZero but also the placement of the generated instruction.

Let's follow SQLite codegen here. We still need to fix `LIMIT 0`,
though.
This commit is contained in:
Pekka Enberg
2024-06-24 21:43:19 +03:00
parent 6290c8167d
commit df230dc830
2 changed files with 6 additions and 7 deletions

View File

@@ -97,13 +97,13 @@ fn translate_select(schema: &Schema, select: Select) -> Result<Program> {
program.emit_insn(Insn::OpenReadAwait);
program.emit_insn(Insn::RewindAsync { cursor_id });
let rewind_await_offset = program.emit_placeholder();
let limit_decr_insn = limit_reg.map(|_| program.emit_placeholder());
let (register_start, register_end) =
translate_columns(&mut program, Some(cursor_id), Some(table), columns);
program.emit_insn(Insn::ResultRow {
register_start,
register_end,
});
let limit_decr_insn = limit_reg.map(|_| program.emit_placeholder());
program.emit_insn(Insn::NextAsync { cursor_id });
program.emit_insn(Insn::NextAwait {
cursor_id,

View File

@@ -94,8 +94,6 @@ pub enum Insn {
},
// Decrement the given register and jump to the given PC if the result is zero.
//
// Unlike in SQLite, if register is already zero, we don't decrement, but take the jump.
DecrJumpZero {
reg: usize,
target_pc: BranchOffset,
@@ -326,11 +324,12 @@ impl Program {
}
Insn::DecrJumpZero { reg, target_pc } => match state.registers[*reg] {
OwnedValue::Integer(n) => {
if n > 0 {
state.registers[*reg] = OwnedValue::Integer(n - 1);
state.pc += 1;
} else {
let n = n - 1;
if n == 0 {
state.pc = *target_pc;
} else {
state.registers[*reg] = OwnedValue::Integer(n);
state.pc += 1;
}
}
_ => unreachable!("DecrJumpZero on non-integer register"),