From 55a444959e2287f57f9f8ffa324de945ea26ba4f Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 16 Oct 2023 11:43:20 +0530 Subject: [PATCH] fix: Make search_link query postgres compatible --- frappe/desk/search.py | 16 +++++++++------- frappe/tests/test_search.py | 30 +++++++----------------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/frappe/desk/search.py b/frappe/desk/search.py index 7a7e5304fd..2a49814382 100644 --- a/frappe/desk/search.py +++ b/frappe/desk/search.py @@ -191,13 +191,15 @@ def search_widget( order_by = f"`tab{doctype}`.idx desc, {order_by_based_on_meta}" if not meta.translated_doctype: - formatted_fields.append( - """(1 / locate({_txt}, `tab{doctype}`.`name`)) as `_relevance`""".format( - _txt=frappe.db.escape((txt or "").replace("%", "").replace("@", "")), - doctype=doctype, - ) - ) - order_by = f"ifnull(_relevance, -9999) desc, {order_by}" + _txt = frappe.db.escape((txt or "").replace("%", "").replace("@", "")) + _relevance = f"(1 / nullif(locate({_txt}, `tab{doctype}`.`name`), 0))" + formatted_fields.append(f"""{_relevance} as `_relevance`""") + # Since we are sorting by alias postgres needs to know number of column we are sorting + if frappe.db.db_type == "mariadb": + order_by = f"ifnull(_relevance, -9999) desc, {order_by}" + elif frappe.db.db_type == "postgres": + # Since we are sorting by alias postgres needs to know number of column we are sorting + order_by = f"{len(formatted_fields)} desc nulls last, {order_by}" ignore_permissions = ( True diff --git a/frappe/tests/test_search.py b/frappe/tests/test_search.py index cb8c352c26..5d1d967228 100644 --- a/frappe/tests/test_search.py +++ b/frappe/tests/test_search.py @@ -2,6 +2,7 @@ # License: MIT. See LICENSE import re +from functools import partial import frappe from frappe.app import make_form_dict @@ -132,7 +133,7 @@ class TestSearch(FrappeTestCase): def test_reference_doctype(self): """search query methods should get reference_doctype if they want""" - results = search( + results = test_search( doctype="User", txt="", filters=None, @@ -143,36 +144,19 @@ class TestSearch(FrappeTestCase): self.assertListEqual(results, []) def test_search_relevance(self): - results = search( - doctype="Language", - txt="e", - filters=None, - page_length=10, - ) - for row in results: + search = partial(test_search, doctype="Language", filters=None, page_length=10) + for row in search(txt="e"): self.assertTrue(row["value"].startswith("e")) - results = search( - doctype="Language", - txt="es", - filters=None, - page_length=10, - ) - for row in results: + for row in search(txt="es"): self.assertIn("es", row["value"]) # Assume that "es" is used at least 10 times, it should now be first frappe.db.set_value("Language", "es", "idx", 10) - results = search( - doctype="Language", - txt="es", - filters=None, - page_length=10, - ) - self.assertEqual("es", results[0]["value"]) + self.assertEqual("es", search(txt="es")[0]["value"]) -def search(*args, **kwargs): +def test_search(*args, **kwargs): search_link(*args, **kwargs) return frappe.response["results"]