fix(search): gallery library per-word search with LIKE escaping (#6584)

Gallery search built a single `%{search}%` LIKE, so multi-word queries only matched the exact adjacent phrase ("red car" missed "a car that is red") and literal % / _ acted as SQL wildcards. Split on whitespace and require each token to match (prompt OR tags OR ai_tags), escaping LIKE wildcards per token; same escaping for the tag filter. Promote _escape_like to public escape_like_pattern() shared helper.

Part of #2123.

Tests: tests/test_gallery_search_multiword.py (5 tests); 4 fail pre-fix, 5 pass post-fix. Neighbors (session_search, gallery null-user, shims): 25 passed.
This commit is contained in:
Merajul Arefin
2026-10-31 13:43:20 +00:00
committed by GitHub
parent 9835c1a7f9
commit 04f8546d9d
3 changed files with 159 additions and 10 deletions
+10 -1
View File
@@ -57,10 +57,19 @@ def _message_to_context(msg: DBChatMessage) -> dict[str, Any]:
}
def _escape_like(value: str) -> str:
def escape_like_pattern(value: str) -> str:
"""Escape SQL LIKE wildcards (``%``, ``_``) and the escape char itself.
Public shared helper for building ``ilike(f"%{...}%", escape="\\\\")``
patterns from user input. Must escape backslash first.
"""
return value.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
def _escape_like(value: str) -> str:
return escape_like_pattern(value)
def _snippet(content: str, query: str, radius: int = 60) -> str:
content = content or ""
query = query or ""