[FIX] model: wrong alias used in read query for multi-inherited field

In commit 04ba0e99, we introduced an optimization for reading inherited fields
in a single query.  There is an issue when you have more than one level of
`_inherits`.  The query looks like:

    SELECT ...
    FROM table0, table1 AS alias1, table2 AS alias2
    WHERE table0.link0 = alias1.id AND table1.link1 = alias2.id AND ...
                                       ^^^^^^
                             should be alias1

This fixes the issue, and adds a test to reproduce it.  The fix is based on
@emiprotechnologies's own proposal, but is cleaner and does not break APIs.
This commit is contained in:
Raphael Collet 2015-05-12 10:29:46 +02:00
parent 1d40f6b8ae
commit 78a20a3dba
2 changed files with 19 additions and 8 deletions

View File

@ -16,6 +16,11 @@ class test_inherits(common.TransactionCase):
self.assertEqual(pallet.field_in_box, 'box')
self.assertEqual(pallet.field_in_pallet, 'pallet')
def test_read_3_levels_inherits(self):
""" Check that we can read an inherited field on 3 levels """
pallet = self.env.ref('test_inherits.pallet_a')
self.assertEqual(pallet.read(['name']), [{'id': pallet.id, 'name': 'Unit A'}])
def test_write_3_levels_inherits(self):
""" Check that we can create an inherits on 3 levels """
pallet = self.env.ref('test_inherits.pallet_a')

View File

@ -2184,14 +2184,20 @@ class BaseModel(object):
:param query: query object on which the JOIN should be added
:return: qualified name of field, to be used in SELECT clause
"""
current_table = self
parent_alias = '"%s"' % current_table._table
while field in current_table._inherit_fields and not field in current_table._columns:
parent_model_name = current_table._inherit_fields[field][0]
parent_table = self.pool[parent_model_name]
parent_alias = self._inherits_join_add(current_table, parent_model_name, query)
current_table = parent_table
return '%s."%s"' % (parent_alias, field)
# INVARIANT: alias is the SQL alias of model._table in query
model, alias = self, self._table
while field in model._inherit_fields and field not in model._columns:
# retrieve the parent model where field is inherited from
parent_model_name = model._inherit_fields[field][0]
parent_model = self.pool[parent_model_name]
parent_field = model._inherits[parent_model_name]
# JOIN parent_model._table AS parent_alias ON alias.parent_field = parent_alias.id
parent_alias, _ = query.add_join(
(alias, parent_model._table, parent_field, 'id', parent_field),
implicit=True,
)
model, alias = parent_model, parent_alias
return '"%s"."%s"' % (alias, field)
def _parent_store_compute(self, cr):
if not self._parent_store: