summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odoo/addons/test_performance/tests/test_performance.py18
-rw-r--r--odoo/fields.py8
2 files changed, 24 insertions, 2 deletions
diff --git a/odoo/addons/test_performance/tests/test_performance.py b/odoo/addons/test_performance/tests/test_performance.py
index 7ace0d3ea96..e880f8a3c75 100644
--- a/odoo/addons/test_performance/tests/test_performance.py
+++ b/odoo/addons/test_performance/tests/test_performance.py
@@ -535,3 +535,21 @@ class TestIrPropertyOptimizations(TransactionCase):
with self.assertQueryCount(5):
self.Bacon.create({'property_eggs': False})
+
+
+@tagged('mapped_perf')
+class TestMapped(TransactionCase):
+
+ def test_relational_mapped(self):
+ # create 1000 records with one line each
+ recs = self.env['test_performance.base'].create([
+ {'name': 'foo%d' % index, 'line_ids': [(0, 0, {'value': index})]}
+ for index in range(1000)
+ ])
+ recs.flush()
+ recs.invalidate_cache()
+
+ # expected same performance as recs.line_ids.mapped('value')
+ with self.assertQueryCount(3):
+ for rec in recs:
+ rec.line_ids.mapped('value')
diff --git a/odoo/fields.py b/odoo/fields.py
index 6ad32a505b6..31d67bc6556 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -1018,8 +1018,12 @@ class Field(MetaField('DummyField', (object,), {})):
# retrieve values in cache, and fetch missing ones
vals = records.env.cache.get_until_miss(records, self)
while len(vals) < len(records):
- # trigger prefetching on remaining records, and continue retrieval
- remaining = records[len(vals):]
+ # It is important to construct a 'remaining' recordset with the
+ # _prefetch_ids of the original recordset, in order to prefetch as
+ # many records as possible. If not done this way, scenarios such as
+ # [rec.line_ids.mapped('name') for rec in recs] would generate one
+ # query per record in `recs`!
+ remaining = records._browse(records.env, records[len(vals):]._ids, records._prefetch_ids)
self.__get__(first(remaining), type(remaining))
vals += records.env.cache.get_until_miss(remaining, self)