diff --git a/frappe/desk/reportview.py b/frappe/desk/reportview.py index df403c76a9..5194f84008 100644 --- a/frappe/desk/reportview.py +++ b/frappe/desk/reportview.py @@ -52,14 +52,24 @@ def get_count() -> int: if is_virtual_doctype(args.doctype): controller = get_controller(args.doctype) - data = frappe.call(controller.get_count, args=args, **args) + count = frappe.call(controller.get_count, args=args, **args) else: args.distinct = sbool(args.distinct) distinct = "distinct " if args.distinct else "" - args.fields = [f"count({distinct}`tab{args.doctype}`.name) as total_count"] - data = execute(**args)[0].get("total_count") + args.limit = cint(args.limit) + if args.limit: + # Only "count until this limit" + args.fields = ["*"] + partial_query = execute(**args, run=0) + count = frappe.db.sql( + f"""with records as ( {partial_query} ) + select count(*) from records""", + )[0][0] + else: + args.fields = [f"count({distinct}`tab{args.doctype}`.name) as total_count"] + count = execute(**args)[0].get("total_count") - return data + return count def execute(doctype, *args, **kwargs): diff --git a/frappe/public/js/frappe/db.js b/frappe/public/js/frappe/db.js index 58329f16d7..b569205aa9 100644 --- a/frappe/public/js/frappe/db.js +++ b/frappe/public/js/frappe/db.js @@ -96,6 +96,7 @@ frappe.db = { }, count: function (doctype, args = {}) { let filters = args.filters || {}; + let limit = args.limit; // has a filter with childtable? const distinct = @@ -111,6 +112,7 @@ frappe.db = { filters, fields, distinct, + limit, }); }, get_link_options(doctype, txt = "", filters = {}) { diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 6adf057391..47c5f1bbeb 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -946,6 +946,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { return frappe.db .count(this.doctype, { filters: this.get_filters_for_args(), + limit: 1001, }) .then((total_count) => { this.total_count = total_count || current_count; diff --git a/frappe/tests/test_db_query.py b/frappe/tests/test_db_query.py index 078bb55c42..f80f73c410 100644 --- a/frappe/tests/test_db_query.py +++ b/frappe/tests/test_db_query.py @@ -1187,7 +1187,7 @@ class TestReportView(FrappeTestCase): "distinct": "false", } ) - list_filter_response = execute_cmd("frappe.desk.reportview.get_count") + count = execute_cmd("frappe.desk.reportview.get_count") frappe.local.form_dict = frappe._dict( { "doctype": "DocType", @@ -1196,8 +1196,8 @@ class TestReportView(FrappeTestCase): } ) dict_filter_response = execute_cmd("frappe.desk.reportview.get_count") - self.assertIsInstance(list_filter_response, int) - self.assertEqual(list_filter_response, dict_filter_response) + self.assertIsInstance(count, int) + self.assertEqual(count, dict_filter_response) # test with child table filter frappe.local.form_dict = frappe._dict( @@ -1218,6 +1218,21 @@ class TestReportView(FrappeTestCase): )[0][0] self.assertEqual(child_filter_response, current_value) + # test with limit + limit = 2 + frappe.local.form_dict = frappe._dict( + { + "doctype": "DocType", + "filters": [["DocType", "is_virtual", "=", 1]], + "fields": [], + "distinct": "false", + "limit": limit, + } + ) + count = execute_cmd("frappe.desk.reportview.get_count") + self.assertIsInstance(count, int) + self.assertLessEqual(count, limit) + def test_reportview_get(self): user = frappe.get_doc("User", "test@example.com") add_child_table_to_blog_post()