fix+test: escape "_" symbol in tags filtering

This commit is contained in:
bigcat88
2025-09-15 17:29:27 +03:00
parent 5f187fe6fb
commit f3cf99d10c
4 changed files with 39 additions and 2 deletions

View File

@@ -1,3 +1,4 @@
from .escape_like import escape_like_prefix
from .filters import apply_metadata_filter, apply_tag_filters
from .ownership import visible_owner_clause
from .projection import is_scalar, project_kv
@@ -10,6 +11,7 @@ from .tags import (
__all__ = [
"apply_tag_filters",
"apply_metadata_filter",
"escape_like_prefix",
"is_scalar",
"project_kv",
"ensure_tags_exist",

View File

@@ -0,0 +1,7 @@
def escape_like_prefix(s: str, escape: str = "!") -> tuple[str, str]:
"""Escapes %, _ and the escape char itself in a LIKE prefix.
Returns (escaped_prefix, escape_char). Caller should append '%' and pass escape=escape_char to .like().
"""
s = s.replace(escape, escape + escape) # escape the escape char first
s = s.replace("%", escape + "%").replace("_", escape + "_") # escape LIKE wildcards
return s, escape

View File

@@ -13,6 +13,7 @@ from ..helpers import (
apply_metadata_filter,
apply_tag_filters,
ensure_tags_exist,
escape_like_prefix,
project_kv,
visible_owner_clause,
)
@@ -527,7 +528,8 @@ async def list_tags_with_usage(
)
if prefix:
q = q.where(Tag.name.like(prefix.strip().lower() + "%"))
escaped, esc = escape_like_prefix(prefix.strip().lower())
q = q.where(Tag.name.like(escaped + "%", escape=esc))
if not include_zero:
q = q.where(func.coalesce(counts_sq.c.cnt, 0) > 0)
@@ -539,7 +541,8 @@ async def list_tags_with_usage(
total_q = select(func.count()).select_from(Tag)
if prefix:
total_q = total_q.where(Tag.name.like(prefix.strip().lower() + "%"))
escaped, esc = escape_like_prefix(prefix.strip().lower())
total_q = total_q.where(Tag.name.like(escaped + "%", escape=esc))
if not include_zero:
total_q = total_q.where(
Tag.name.in_(select(AssetInfoTag.tag_name).group_by(AssetInfoTag.tag_name))