diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index c73fa5ea09..596f69d2dd 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -171,11 +171,19 @@ class DatabaseQuery(object): fields = [] + # Wrapping fields with grave quotes to allow support for sql keywords + # TODO: Add support for wrapping fields with sql functions and distinct keyword for field in self.fields: - if field.strip().startswith(("`", "*", '"', "'")) or "(" in field: + stripped_field = field.strip().lower() + skip_wrapping = any([ + stripped_field.startswith(("`", "*", '"', "'")), + "(" in stripped_field, + "distinct" in stripped_field, + ]) + if skip_wrapping: fields.append(field) elif "as" in field.lower().split(" "): - col, _, new = field.split()[-3:] + col, _, new = field.split() fields.append("`{0}` as {1}".format(col, new)) else: fields.append("`{0}`".format(field)) diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 2ac0cb2631..6fbf247404 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -133,8 +133,27 @@ class TestDB(unittest.TestCase): self.assertEqual(list(frappe.get_all("ToDo", fields=[random_field], limit=1)[0])[0], random_field) self.assertEqual(list(frappe.get_all("ToDo", fields=["{0} as total".format(random_field)], limit=1)[0])[0], "total") - # Testing read for distinct keyword - Check if result contains total field - self.assertEqual(list(frappe.get_all("ToDo", fields=["distinct {0} as total".format(random_field)], limit=1)[0])[0], "total") + # Testing read for distinct and sql functions + self.assertEqual(list( + frappe.get_all("ToDo", + fields=["`{0}` as total".format(random_field)], + distinct=True, + limit=1, + )[0] + )[0], "total") + self.assertEqual(list( + frappe.get_all("ToDo", + fields=["`{0}`".format(random_field)], + distinct=True, + limit=1, + )[0] + )[0], random_field) + self.assertEqual(list( + frappe.get_all("ToDo", + fields=["count(`{0}`)".format(random_field)], + limit=1 + )[0] + )[0], "count" if frappe.conf.db_type == "postgres" else "count(`{0}`)".format(random_field)) # Testing update frappe.db.set_value(test_doctype, random_doc, random_field, random_value)