Merge pull request #35092 from akhilnarang/return-query-object

feat(qb_query)!: return query object if requested
This commit is contained in:
Akhil Narang 2025-12-09 12:21:48 +05:30 committed by GitHub
commit 66ef5bf2ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 26 deletions

View file

@ -157,7 +157,7 @@ class TestServerScript(IntegrationTestCase):
self.assertEqual(frappe.get_doc("Server Script", "test_return_value").execute_method(), "hello")
def test_permission_query(self):
sql = frappe.db.get_list("ToDo", run=False)
sql = frappe.db.get_list("ToDo", run=False).get_sql()
self.assertTrue("where (1 = 1)" in sql.lower())
self.assertTrue(isinstance(frappe.db.get_list("ToDo"), list))

View file

@ -200,8 +200,7 @@ class DatabaseQuery:
query = frappe.qb.get_query(**kwargs)
if not run:
# Return the SQL query string instead of executing
return str(query.get_sql())
return query
# Run the query
if pluck:

View file

@ -1047,28 +1047,32 @@ class TestDBQuery(IntegrationTestCase):
self.assertIn("count", result[0])
def test_coalesce_with_in_ops(self):
self.assertNotIn("IF", frappe.get_all("User", {"first_name": ("in", ["a", "b"])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", ["a", None])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", ["a", ""])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", [])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", ["a"])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", [])}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", [""])}, run=0))
self.assertNotIn("IF", frappe.get_all("User", {"first_name": ("in", ["a", "b"])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", ["a", None])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", ["a", ""])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("in", [])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", ["a"])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", [])}, run=0).get_sql())
self.assertIn("IFNULL", frappe.get_all("User", {"first_name": ("not in", [""])}, run=0).get_sql())
# primary key is never nullable
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ["a", None])}, run=0))
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ["a", ""])}, run=0))
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", (""))}, run=0))
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ())}, run=0))
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ["a", None])}, run=0).get_sql())
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ["a", ""])}, run=0).get_sql())
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", (""))}, run=0).get_sql())
self.assertNotIn("IFNULL", frappe.get_all("User", {"name": ("in", ())}, run=0).get_sql())
def test_coalesce_with_datetime_ops(self):
self.assertNotIn("IFNULL", frappe.get_all("User", {"last_active": (">", "2022-01-01")}, run=0))
self.assertNotIn("IFNULL", frappe.get_all("User", {"creation": ("<", "2022-01-01")}, run=0))
self.assertNotIn(
"IFNULL", frappe.get_all("User", {"last_active": (">", "2022-01-01")}, run=0).get_sql()
)
self.assertNotIn("IFNULL", frappe.get_all("User", {"creation": ("<", "2022-01-01")}, run=0).get_sql())
self.assertNotIn(
"IFNULL",
frappe.get_all("User", {"last_active": ("between", ("2022-01-01", "2023-01-01"))}, run=0),
frappe.get_all(
"User", {"last_active": ("between", ("2022-01-01", "2023-01-01"))}, run=0
).get_sql(),
)
self.assertIn("IFNULL", frappe.get_all("User", {"last_active": ("<", "2022-01-01")}, run=0))
self.assertIn("IFNULL", frappe.get_all("User", {"last_active": ("<", "2022-01-01")}, run=0).get_sql())
def test_ambiguous_linked_tables(self):
from frappe.desk.reportview import get
@ -1145,16 +1149,16 @@ class TestDBQuery(IntegrationTestCase):
self.assertEqual(count[1], frappe.db.count("Language"))
def test_ifnull_none(self):
query = frappe.get_all("DocField", {"fieldname": None}, run=0)
query = frappe.get_all("DocField", {"fieldname": None}, run=0).get_sql()
self.assertIn("IS NULL", query)
self.assertNotIn("\\'", query)
self.assertNotIn("ifnull", query)
self.assertFalse(frappe.get_all("DocField", {"name": None}))
self.assertFalse(frappe.get_all("DocField", {"parent": None}))
self.assertNotIn("0", frappe.get_all("DocField", {"parent": None}, run=0))
self.assertNotIn("0", frappe.get_all("DocField", {"parent": None}, run=0).get_sql())
def test_ifnull_fallback_types(self):
query = frappe.get_all("DocField", {"fieldname": ("!=", None)}, run=0)
query = frappe.get_all("DocField", {"fieldname": ("!=", None)}, run=0).get_sql()
# Fallbacks should always be of correct type
self.assertIn("''", query)
self.assertNotIn("0", query)

View file

@ -285,10 +285,10 @@ class TestNestedSet(IntegrationTestCase):
inclusive_link = {"link_field": ("descendants of (inclusive)", record)}
# db_query
self.assertNotIn(record, frappe.get_all(TEST_DOCTYPE, exclusive_filter, run=0))
self.assertIn(record, frappe.get_all(TEST_DOCTYPE, inclusive_filter, run=0))
self.assertNotIn(record, frappe.get_all(linked_doctype, exclusive_link, run=0))
self.assertIn(record, frappe.get_all(linked_doctype, inclusive_link, run=0))
self.assertNotIn(record, frappe.get_all(TEST_DOCTYPE, exclusive_filter, run=0).get_sql())
self.assertIn(record, frappe.get_all(TEST_DOCTYPE, inclusive_filter, run=0).get_sql())
self.assertNotIn(record, frappe.get_all(linked_doctype, exclusive_link, run=0).get_sql())
self.assertIn(record, frappe.get_all(linked_doctype, inclusive_link, run=0).get_sql())
# QB
self.assertNotIn(record, str(frappe.qb.get_query(TEST_DOCTYPE, filters=exclusive_filter)))

View file

@ -179,7 +179,7 @@ class TestPerformance(IntegrationTestCase):
frappe.get_list("User")
def test_no_ifnull_checks(self):
query = frappe.get_all("DocType", {"autoname": ("is", "set")}, run=0).lower()
query = frappe.get_all("DocType", {"autoname": ("is", "set")}, run=0).get_sql().lower()
self.assertNotIn("coalesce", query)
self.assertNotIn("ifnull", query)