summaryrefslogtreecommitdiff
path: root/openerp/osv/expression.py
diff options
context:
space:
mode:
authorRaphael Collet <rco@openerp.com>2015-09-04 10:06:11 +0200
committerRaphael Collet <rco@openerp.com>2015-09-04 13:25:51 +0200
commitf5e5bbdae0d799b10fa6e59547d14b1a42e87f89 (patch)
treee34534dd7042c4375ed982da37c1f609015ab15d /openerp/osv/expression.py
parent1658bee8d45d37d7fabd0ac230b894a4a6b89303 (diff)
[FIX] expression: fix search on one2many field with inherited inverse field
Consider the following setting: - on model A, field F is computed, stored, and depends on field G - on model A, field one2many G to model B, with inverse field H - on model B, field many2one H is inherited (_inherits) from model C - on model C, field many2one H is stored When adding records of model B, the field F must be recomputed. In order to determine which records to recompute, one searches model A with a domain like [(G, 'in', ids)]. In expression.py, this is resolved with an SQL query like select H from B where id in {ids} This query fails, since the field H is not stored in model B. This happens in general if H is not stored (it may be any computed field). In that case, one should instead browse records from B, and read field H through the ORM. A test case has been added: it introduces a many2one field in a parent model, and a one2many field using the inherited many2one on a child model. The test checks whether one can search on the one2many field.
Diffstat (limited to 'openerp/osv/expression.py')
-rw-r--r--openerp/osv/expression.py12
1 files changed, 9 insertions, 3 deletions
diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py
index 7f962c260fa..dedd043ca90 100644
--- a/openerp/osv/expression.py
+++ b/openerp/osv/expression.py
@@ -138,6 +138,7 @@ import traceback
import openerp.modules
from . import fields
+from .. import SUPERUSER_ID
from ..models import MAGIC_COLUMNS, BaseModel
import openerp.tools as tools
@@ -941,11 +942,16 @@ class expression(object):
call_null = False
push(create_substitution_leaf(leaf, FALSE_LEAF, model))
else:
- ids2 = select_from_where(cr, column._fields_id, comodel._table, 'id', ids2, operator)
- if ids2:
+ # determine ids1 <-- column._fields_id --- ids2
+ if comodel._fields[column._fields_id].store:
+ ids1 = select_from_where(cr, column._fields_id, comodel._table, 'id', ids2, operator)
+ else:
+ recs = comodel.browse(cr, SUPERUSER_ID, ids2, {'prefetch_fields': False})
+ ids1 = recs.mapped(column._fields_id).ids
+ if ids1:
call_null = False
o2m_op = 'not in' if operator in NEGATIVE_TERM_OPERATORS else 'in'
- push(create_substitution_leaf(leaf, ('id', o2m_op, ids2), model))
+ push(create_substitution_leaf(leaf, ('id', o2m_op, ids1), model))
if call_null:
o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'