From dc852fee8c97848f99b28f4bbf63e32450343071 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 16 Feb 2025 10:14:02 +0200 Subject: [PATCH] expr.rs: Like: use shared impl in translate_expr() and translate_condition_expr() --- core/translate/expr.rs | 109 +++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/core/translate/expr.rs b/core/translate/expr.rs index bb5965fde..156221c1f 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -396,49 +396,9 @@ pub fn translate_condition_expr( program.resolve_label(jump_target_when_true, program.offset()); } } - ast::Expr::Like { - lhs, - not, - op, - rhs, - escape: _, - } => { + ast::Expr::Like { not, .. } => { let cur_reg = program.alloc_register(); - match op { - ast::LikeOperator::Like | ast::LikeOperator::Glob => { - let start_reg = program.alloc_registers(2); - let mut constant_mask = 0; - translate_and_mark( - program, - Some(referenced_tables), - lhs, - start_reg + 1, - resolver, - )?; - let _ = - translate_expr(program, Some(referenced_tables), rhs, start_reg, resolver)?; - if matches!(rhs.as_ref(), ast::Expr::Literal(_)) { - program.mark_last_insn_constant(); - constant_mask = 1; - } - let func = match op { - ast::LikeOperator::Like => ScalarFunc::Like, - ast::LikeOperator::Glob => ScalarFunc::Glob, - _ => unreachable!(), - }; - program.emit_insn(Insn::Function { - constant_mask, - start_reg, - dest: cur_reg, - func: FuncCtx { - func: Func::Scalar(func), - arg_count: 2, - }, - }); - } - ast::LikeOperator::Match => todo!(), - ast::LikeOperator::Regexp => todo!(), - } + translate_like_base(program, Some(referenced_tables), expr, cur_reg, resolver)?; if !*not { emit_cond_jump(program, condition_metadata, cur_reg); } else if condition_metadata.jump_if_condition_is_true { @@ -1955,7 +1915,21 @@ pub fn translate_expr( ast::Expr::InSelect { .. } => todo!(), ast::Expr::InTable { .. } => todo!(), ast::Expr::IsNull(_) => todo!(), - ast::Expr::Like { .. } => todo!(), + ast::Expr::Like { not, .. } => { + let like_reg = if *not { + program.alloc_register() + } else { + target_register + }; + translate_like_base(program, referenced_tables, expr, like_reg, resolver)?; + if *not { + program.emit_insn(Insn::Not { + reg: like_reg, + dest: target_register, + }); + } + Ok(target_register) + } ast::Expr::Literal(lit) => match lit { ast::Literal::Numeric(val) => { let maybe_int = val.parse::(); @@ -2145,6 +2119,55 @@ pub fn translate_expr( } } +fn translate_like_base( + program: &mut ProgramBuilder, + referenced_tables: Option<&[TableReference]>, + expr: &ast::Expr, + target_register: usize, + resolver: &Resolver, +) -> Result { + let ast::Expr::Like { + lhs, + op, + rhs, + escape: _, + .. + } = expr + else { + crate::bail_parse_error!("expected Like expression"); + }; + match op { + ast::LikeOperator::Like | ast::LikeOperator::Glob => { + let start_reg = program.alloc_registers(2); + let mut constant_mask = 0; + translate_and_mark(program, referenced_tables, lhs, start_reg + 1, resolver)?; + let _ = translate_expr(program, referenced_tables, rhs, start_reg, resolver)?; + if matches!(rhs.as_ref(), ast::Expr::Literal(_)) { + program.mark_last_insn_constant(); + constant_mask = 1; + } + let func = match op { + ast::LikeOperator::Like => ScalarFunc::Like, + ast::LikeOperator::Glob => ScalarFunc::Glob, + _ => unreachable!(), + }; + program.emit_insn(Insn::Function { + constant_mask, + start_reg, + dest: target_register, + func: FuncCtx { + func: Func::Scalar(func), + arg_count: 2, + }, + }); + } + ast::LikeOperator::Match => todo!(), + ast::LikeOperator::Regexp => todo!(), + } + + Ok(target_register) +} + /// Emits a whole insn for a function call. /// Assumes the number of parameters is valid for the given function. /// Returns the target register for the function.