From 6449c79e93c579ac429110fd5f086a61439abfc3 Mon Sep 17 00:00:00 2001 From: "l.gualtieri" Date: Sat, 1 Mar 2025 13:21:20 +0100 Subject: [PATCH] Escape character is ignored in LIKE function #1051 --- core/translate/expr.rs | 18 +++++++++++++++--- core/vdbe/explain.rs | 10 +++++++++- testing/like.test | 4 ++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 247aa124a..8a075bb54 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -2159,7 +2159,7 @@ fn translate_like_base( lhs, op, rhs, - escape: _, + escape, .. } = expr else { @@ -2167,10 +2167,22 @@ fn translate_like_base( }; match op { ast::LikeOperator::Like | ast::LikeOperator::Glob => { - let start_reg = program.alloc_registers(2); + let arg_count = if matches!(escape, Some(_)) { 3 } else { 2 }; + let start_reg = program.alloc_registers(arg_count); 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 arg_count == 3 { + if let Some(escape) = escape { + translate_and_mark( + program, + referenced_tables, + escape, + start_reg + 2, + resolver, + )?; + } + } if matches!(rhs.as_ref(), ast::Expr::Literal(_)) { program.mark_last_insn_constant(); constant_mask = 1; @@ -2186,7 +2198,7 @@ fn translate_like_base( dest: target_register, func: FuncCtx { func: Func::Scalar(func), - arg_count: 2, + arg_count: arg_count, }, }); } diff --git a/core/vdbe/explain.rs b/core/vdbe/explain.rs index a609fc667..2e8ce105e 100644 --- a/core/vdbe/explain.rs +++ b/core/vdbe/explain.rs @@ -1,6 +1,7 @@ use crate::vdbe::builder::CursorType; use super::{Insn, InsnReference, OwnedValue, Program}; +use crate::function::{Func, ScalarFunc}; use std::rc::Rc; pub fn insn_to_str( @@ -936,7 +937,14 @@ pub fn insn_to_str( *constant_mask, *start_reg as i32, *dest as i32, - OwnedValue::build_text(&func.func.to_string()), + { + let s = if matches!(&func.func, Func::Scalar(ScalarFunc::Like)) { + format!("like({})", func.arg_count) + } else { + func.func.to_string() + }; + OwnedValue::build_text(&s) + }, 0, if func.arg_count == 0 { format!("r[{}]=func()", dest) diff --git a/testing/like.test b/testing/like.test index 8d4456406..e813d6251 100755 --- a/testing/like.test +++ b/testing/like.test @@ -74,6 +74,10 @@ John|Johnson Stephen|Stephens Robert|Roberts} +do_execsql_test where-like-another-column-prefix { + select count(*) from users where last_name like 'Pe#rry' escape '#'; +} {19} + do_execsql_test where-like-impossible { select * from products where 'foobar' like 'fooba'; } {}