From 6d32ffcc6c7352dfa5f752fa5866394dfc0594ca Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 2 May 2025 11:51:11 +0530 Subject: [PATCH] perf: optimize `!=` operator when field can be null --- frappe/model/db_query.py | 3 +++ frappe/tests/test_db_query.py | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 04c4b4e95f..c5e8e1115f 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -924,6 +924,9 @@ from {tables} # intersection instead of full table scans. if fallback == value and f.operator == "=": condition = f"( {column_name} is NULL OR {column_name} {f.operator} {value} )" + elif fallback == value and f.operator == "!=": + # NULL != anything is always NULL, so won't match + condition = f"{column_name} {f.operator} {value}" else: condition = f"ifnull({column_name}, {fallback}) {f.operator} {value}" diff --git a/frappe/tests/test_db_query.py b/frappe/tests/test_db_query.py index 25d59d66ff..7b43201407 100644 --- a/frappe/tests/test_db_query.py +++ b/frappe/tests/test_db_query.py @@ -1200,6 +1200,14 @@ class TestDBQuery(IntegrationTestCase): query = frappe.get_all("DocField", {"fieldname": None}, run=0) self.assertIn("''", query) self.assertNotIn("\\'", query) + self.assertNotIn("ifnull", query) + + def test_ifnull_fallback_types(self): + query = frappe.get_all("DocField", {"fieldname": ("!=", None)}, run=0) + # Fallbacks should always be of correct type + self.assertIn("''", query) + self.assertNotIn("0", query) + self.assertNotIn("ifnull", query) class TestReportView(IntegrationTestCase):