diff --git a/src/search/fts.rs b/src/search/fts.rs index ab46850..276a0fd 100644 --- a/src/search/fts.rs +++ b/src/search/fts.rs @@ -52,12 +52,18 @@ pub fn to_fts_query(raw: &str, mode: FtsQueryMode) -> String { return String::new(); } + // FTS5 boolean operators are case-sensitive uppercase keywords. + // Pass them through unquoted so users can write "switch AND health". + const FTS5_OPERATORS: &[&str] = &["AND", "OR", "NOT", "NEAR"]; + let mut result = String::with_capacity(trimmed.len() + 20); for (i, token) in trimmed.split_whitespace().enumerate() { if i > 0 { result.push(' '); } - if let Some(stem) = token.strip_suffix('*') + if FTS5_OPERATORS.contains(&token) { + result.push_str(token); + } else if let Some(stem) = token.strip_suffix('*') && !stem.is_empty() && stem.chars().all(|c| c.is_alphanumeric() || c == '_') {