Fix evaluation of ISNULL/NOTNULL in OR expressions

Previously, the `jump_if_condition_is_true` flag was not respected. As a
result, for expressions like <`ISNULL`/`NOTNULL`> `OR` <rhs>, the <rhs>
expression was evaluated even when the left-hand side was true, and its
value was incorrectly used as the final result.
This commit is contained in:
Piotr Rzysko
2025-06-27 08:13:02 +02:00
parent e162b56d01
commit 116df2ec86
2 changed files with 30 additions and 8 deletions

View File

@@ -362,18 +362,32 @@ pub fn translate_condition_expr(
ast::Expr::NotNull(expr) => {
let cur_reg = program.alloc_register();
translate_expr(program, Some(referenced_tables), expr, cur_reg, resolver)?;
program.emit_insn(Insn::IsNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_false,
});
if condition_metadata.jump_if_condition_is_true {
program.emit_insn(Insn::NotNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_true,
});
} else {
program.emit_insn(Insn::IsNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_false,
});
}
}
ast::Expr::IsNull(expr) => {
let cur_reg = program.alloc_register();
translate_expr(program, Some(referenced_tables), expr, cur_reg, resolver)?;
program.emit_insn(Insn::NotNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_false,
});
if condition_metadata.jump_if_condition_is_true {
program.emit_insn(Insn::IsNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_true,
});
} else {
program.emit_insn(Insn::NotNull {
reg: cur_reg,
target_pc: condition_metadata.jump_target_when_false,
});
}
}
ast::Expr::Unary(_, _) => {
// This is an inefficient implementation for op::NOT, because translate_expr() will emit an Insn::Not,