From 6595cfdf0c4ea64fd9271a06107cfa90297f246d Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 6 Apr 2017 15:27:21 +0200 Subject: [PATCH] [FIX] expression: avoid useless query when searching on x2many sub-field Searching on a domain like `[('m2m.sub', operator, value)]` currently does something like: right_ids = comodel.search([('sub', operator, value)]).ids table_ids = model.search([('m2m', 'in', right_ids)]).ids and reduces the domain triple to `('id', 'in', table_ids)`. The domain triple can actually be reduced to `('m2m', 'in', right_ids)`. With this reduction, the search on the field `m2m` will be done as part of the main query. And this will also enable the optimization of the former fix! --- openerp/addons/base/tests/test_expression.py | 12 ++++++------ openerp/osv/expression.py | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py index ffa22cc252a..75ee10a508f 100644 --- a/openerp/addons/base/tests/test_expression.py +++ b/openerp/addons/base/tests/test_expression.py @@ -178,8 +178,8 @@ class test_expression(common.TransactionCase): self.assertEqual(set(partner_ids), set([p_aa]), "_auto_join off: ('bank_ids.name', 'like', '..'): incorrect result") # Test produced queries - self.assertEqual(len(self.query_list), 3, - "_auto_join off: ('bank_ids.name', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)") + self.assertEqual(len(self.query_list), 2, + "_auto_join off: ('bank_ids.name', 'like', '..') should produce 2 queries (1 in res_partner_bank, 1 on res_partner)") sql_query = self.query_list[0].get_sql() self.assertIn('res_partner_bank', sql_query[0], "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect main table") @@ -190,7 +190,7 @@ class test_expression(common.TransactionCase): self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect parameter") - sql_query = self.query_list[2].get_sql() + sql_query = self.query_list[1].get_sql() self.assertIn('res_partner', sql_query[0], "_auto_join off: ('bank_ids.name', 'like', '..') third query incorrect main table") self.assertIn('"res_partner"."id" in (%s)', sql_query[1], @@ -205,8 +205,8 @@ class test_expression(common.TransactionCase): self.assertEqual(set(partner_ids), set([p_a, p_b]), "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]): incorrect result") # Test produced queries - self.assertEqual(len(self.query_list), 5, - "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 5 queries (1 in res_partner_bank, 4 on res_partner)") + self.assertEqual(len(self.query_list), 3, + "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 3 queries (1 in res_partner_bank, 2 on res_partner)") # Do: one2many with _auto_join partner_bank_ids_col._auto_join = True @@ -437,7 +437,7 @@ class test_expression(common.TransactionCase): self.assertTrue(set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries - self.assertEqual(len(self.query_list), 5, + self.assertEqual(len(self.query_list), 4, "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect") # Do: ('child_ids.state_id.country_id.code', 'like', '..') with _auto_join diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index b9e2a396a3a..235416dc08d 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -869,8 +869,7 @@ class expression(object): # Making search easier when there is a left operand as column.o2m or column.m2m elif len(path) > 1 and column and column._type in ['many2many', 'one2many']: right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context) - table_ids = model.search(cr, uid, [(path[0], 'in', right_ids)], context=dict(context, active_test=False)) - leaf.leaf = ('id', 'in', table_ids) + leaf.leaf = (path[0], 'in', right_ids) push(leaf) elif not column: