From d6b19dcaa19cd4cffdb6c92740db2716bd2fe46d Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 27 Sep 2026 21:09:54 +0200 Subject: [PATCH] fix: on PostgreSQL, searching automations or filtering models by a non-ASCII word finds nothing (#31423) On PostgreSQL with ENABLE_ORJSON off (the default), searching automations by a word from their prompt, or filtering models by a tag, found nothing when the word was non-ASCII, for example Chinese. SQLite, and PostgreSQL with ENABLE_ORJSON on, were fine. With the default setting non-ASCII text is saved as \uXXXX codes, and PostgreSQL reads the backslash in a search pattern as a special character, so the search never matched. Special characters in the search text are now taken literally, so these searches work on both databases, and a % or _ typed into them now matches only itself. Fixes #31422 --- backend/open_webui/models/automations.py | 2 +- backend/open_webui/models/models.py | 4 +++- backend/open_webui/models/prompts.py | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/models/automations.py b/backend/open_webui/models/automations.py index 8c7f6089e3..954026cfc8 100644 --- a/backend/open_webui/models/automations.py +++ b/backend/open_webui/models/automations.py @@ -195,7 +195,7 @@ class AutomationTable: stmt = stmt.filter( or_( Automation.name.ilike(f'%{query}%'), - *(data_text.ilike(f'%{variant}%') for variant in json_text_variants(query)), + *(data_text.icontains(variant, autoescape=True) for variant in json_text_variants(query)), ) ) diff --git a/backend/open_webui/models/models.py b/backend/open_webui/models/models.py index 8da346ab70..d48f1e9008 100755 --- a/backend/open_webui/models/models.py +++ b/backend/open_webui/models/models.py @@ -392,7 +392,9 @@ class ModelsTable: else: meta_text = func.lower(cast(Model.meta, String)) variants = json_text_variants(tag.lower()) - stmt = stmt.filter(or_(*(meta_text.like(f'%"{variant}"%') for variant in variants))) + stmt = stmt.filter( + or_(*(meta_text.contains(f'"{variant}"', autoescape=True) for variant in variants)) + ) order_by = filter.get('order_by') direction = filter.get('direction') diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py index f0e4a3e9b8..75cc93b5a8 100644 --- a/backend/open_webui/models/prompts.py +++ b/backend/open_webui/models/prompts.py @@ -346,7 +346,10 @@ class PromptsTable: # Fallback for dialects with no JSON array function: LIKE on the text. tags_text = func.lower(cast(Prompt.tags, String)) tag_clause = or_( - *(tags_text.like(f'%"{variant}"%') for variant in json_text_variants(tag_lower)) + *( + tags_text.contains(f'"{variant}"', autoescape=True) + for variant in json_text_variants(tag_lower) + ) ) tag_lower = None