From 116df2ec86b73bfe7d307ea8bb502e44e192e5ba Mon Sep 17 00:00:00 2001 From: Piotr Rzysko Date: Fri, 27 Jun 2025 08:13:02 +0200 Subject: [PATCH] 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` , the expression was evaluated even when the left-hand side was true, and its value was incorrectly used as the final result. --- core/translate/expr.rs | 30 ++++++++++++++++++++++-------- testing/where.test | 8 ++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/core/translate/expr.rs b/core/translate/expr.rs index c8ee0430f..4ff41322b 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -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, diff --git a/testing/where.test b/testing/where.test index 71e54b899..42a51e9d8 100755 --- a/testing/where.test +++ b/testing/where.test @@ -62,10 +62,18 @@ do_execsql_test where-clause-isnull { select count(1) from users where last_name isnull; } {0} +do_execsql_test where-clause-isnull-or-false { + select count(1) from users where null isnull or 1 != 1; +} {10000} + do_execsql_test where-clause-notnull { select count(1) from users where last_name not null; } {10000} +do_execsql_test where-clause-notnull-or-false { + select count(1) from users where last_name not null or 1 != 1; +} {10000} + do_execsql_test where-clause-ne { select count(1) from users where id != 2000; } {9999}