diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 359bb8cf7..ce797c75a 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -191,15 +191,6 @@ fn translate_in_list( dest_if_null: BranchOffset, resolver: &Resolver, ) -> Result<()> { - // Disclamer: SQLite does this opt during parsing (https://github.com/sqlite/sqlite/blob/833fb1ef59b1c62fb2b00c7a121a5b5171f8a85e/src/parse.y#L1425) - // But we're the cool kids so we gotta do during translation :) - if rhs.is_empty() { - program.emit_insn(Insn::Goto { - target_pc: dest_if_false, - }); - return Ok(()); - } - let lhs_reg = expr_code_vector(program, lhs); let _ = translate_expr(program, referenced_tables, lhs, lhs_reg, resolver)?; let mut check_null_reg = 0; diff --git a/parser/src/parser.rs b/parser/src/parser.rs index b4188df44..b134f9f95 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -1723,11 +1723,23 @@ impl<'a> Parser<'a> { _ => { let exprs = self.parse_expr_list()?; eat_expect!(self, TK_RP); - Box::new(Expr::InList { - lhs: result, - not, - rhs: exprs, - }) + // Expressions in the form: + // lhs IN () + // lhs NOT IN () + // can be simplified to constants 0 (false) and 1 (true), respectively. + // + // todo: should check if lhs has a function. If so, this optimization cannot + // be done. + if exprs.is_empty() { + let name = if not { "1" } else { "0" }; + Box::new(Expr::Literal(Literal::Numeric(name.into()))) + } else { + Box::new(Expr::InList { + lhs: result, + not, + rhs: exprs, + }) + } } } }