From 59b440cb280b69e44c1739f894c6d3f1ea3900f6 Mon Sep 17 00:00:00 2001 From: Aarol D'Souza <98270103+AarDG10@users.noreply.github.com> Date: Mon, 12 Jan 2026 12:06:28 +0530 Subject: [PATCH] fix(search): make QB DB-Aware when using Locate (#35796) * fix: make QB DB-Aware when choosing Locate * fix(test): adjust test to check smarter qb choice based on db --- frappe/query_builder/functions.py | 17 +++++++++++++++-- frappe/tests/test_query.py | 19 +++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/frappe/query_builder/functions.py b/frappe/query_builder/functions.py index aaf0196542..98cd501be2 100644 --- a/frappe/query_builder/functions.py +++ b/frappe/query_builder/functions.py @@ -25,8 +25,21 @@ class Concat_ws(Function): class Locate(Function): - def __init__(self, *terms, **kwargs): - super().__init__("LOCATE", *terms, **kwargs) + def __init__(self, needle, haystack, **kwargs): + super().__init__("LOCATE", needle, haystack, **kwargs) + + +class Strpos(Function): + def __init__(self, needle, haystack, **kwargs): + super().__init__("STRPOS", haystack, needle, **kwargs) + + +class Instr(Function): + def __init__(self, needle, haystack, **kwargs): + super().__init__("INSTR", haystack, needle, **kwargs) + + +Locate = ImportMapper({db_type_is.MARIADB: Locate, db_type_is.POSTGRES: Strpos, db_type_is.SQLITE: Instr}) # for backward compatibility diff --git a/frappe/tests/test_query.py b/frappe/tests/test_query.py index 83d2124d5d..86c627e490 100644 --- a/frappe/tests/test_query.py +++ b/frappe/tests/test_query.py @@ -1812,10 +1812,21 @@ class TestQuery(IntegrationTestCase): ], ) sql = query.get_sql() - self.assertIn( - self.normalize_sql("1/NULLIF(LOCATE('test',`name`),0) `relevance`"), - self.normalize_sql(sql), - ) + if frappe.db.db_type == "mariadb": + self.assertIn( + self.normalize_sql("1/NULLIF(LOCATE('test',`name`),0) `relevance`"), + self.normalize_sql(sql), + ) + elif frappe.db.db_type == "postgres": + self.assertIn( + self.normalize_sql("1/NULLIF(STRPOS(`name`,'test'),0) `relevance`"), + self.normalize_sql(sql), + ) + elif frappe.db.db_type == "sqlite": + self.assertIn( + self.normalize_sql("1/NULLIF(INSTR(`name`,'test'),0) `relevance`"), + self.normalize_sql(sql), + ) # Test multiple operators in fields query = frappe.qb.get_query(