From ffd8bba37319fd3cd421e5061fb2d06eaf342ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Romero?= Date: Thu, 8 Oct 2026 13:55:43 +0000 Subject: [PATCH] perf: stream contact wildcard bindings --- .../flectar-mail-core/src/db/repo/contacts.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/flectar-mail-core/src/db/repo/contacts.rs b/crates/flectar-mail-core/src/db/repo/contacts.rs index b591fd27..b7922f3b 100644 --- a/crates/flectar-mail-core/src/db/repo/contacts.rs +++ b/crates/flectar-mail-core/src/db/repo/contacts.rs @@ -241,11 +241,20 @@ fn folded_clauses(query: &str, bind: &mut Vec>) let mut clauses = Vec::with_capacity(tokens.len()); for tok in tokens { // Escape LIKE wildcards so a literal % or _ in the query can't scan-match. - let esc = tok - .replace('\\', "\\\\") - .replace('%', "\\%") - .replace('_', "\\_"); - bind.push(Box::new(format!("%{esc}%"))); + let extra = tok + .bytes() + .filter(|byte| matches!(byte, b'\\' | b'%' | b'_')) + .count(); + let mut pattern = String::with_capacity(tok.len() + extra + 2); + pattern.push('%'); + for character in tok.chars() { + if matches!(character, '\\' | '%' | '_') { + pattern.push('\\'); + } + pattern.push(character); + } + pattern.push('%'); + bind.push(Box::new(pattern)); clauses.push(format!( "LOWER(COALESCE(folded, email) || ' ' || COALESCE(job_title, '') || ' ' || COALESCE(website, '') || ' ' || COALESCE(postal_address, ''))