diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py index c43dda85e9b..49bc7d57ca1 100644 --- a/openerp/addons/base/tests/test_expression.py +++ b/openerp/addons/base/tests/test_expression.py @@ -114,6 +114,12 @@ class test_expression(common.TransactionCase): # Test2: inheritance + relational fields user_ids = users_obj.search(cr, uid, [('child_ids.name', 'like', 'test_B')]) self.assertEqual(set(user_ids), set([b1]), 'searching through inheritance failed') + + # Special =? operator mean "is equal if right is set, otherwise always True" + user_ids = users_obj.search(cr, uid, [('name', 'like', 'test'), ('parent_id', '=?', False)]) + self.assertEqual(set(user_ids), set([a, b1, b2]), '(x =? False) failed') + user_ids = users_obj.search(cr, uid, [('name', 'like', 'test'), ('parent_id', '=?', b1_user.partner_id.id)]) + self.assertEqual(set(user_ids), set([b2]), '(x =? id) failed') def test_20_auto_join(self): registry, cr, uid = self.registry, self.cr, self.uid diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index bf02c12a228..ba00c2caa91 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -598,6 +598,15 @@ class ExtendedLeaf(object): self.leaf = normalize_leaf(self.leaf) return True +def create_substitution_leaf(leaf, new_elements, new_model=None): + """ From a leaf, create a new leaf (based on the new_elements tuple + and new_model), that will have the same join context. Used to + insert equivalent leafs in the processing stack. """ + if new_model is None: + new_model = leaf.model + new_join_context = [tuple(context) for context in leaf.join_context] + new_leaf = ExtendedLeaf(new_elements, new_model, join_context=new_join_context) + return new_leaf class expression(object): """ Parse a domain expression @@ -715,16 +724,6 @@ class expression(object): return ids + recursive_children(ids2, model, parent_field) return [(left, 'in', recursive_children(ids, left_model, parent or left_model._parent_name))] - def create_substitution_leaf(leaf, new_elements, new_model=None): - """ From a leaf, create a new leaf (based on the new_elements tuple - and new_model), that will have the same join context. Used to - insert equivalent leafs in the processing stack. """ - if new_model is None: - new_model = leaf.model - new_join_context = [tuple(context) for context in leaf.join_context] - new_leaf = ExtendedLeaf(new_elements, new_model, join_context=new_join_context) - return new_leaf - def pop(): """ Pop a leaf to process. """ return self.stack.pop() @@ -1153,7 +1152,8 @@ class expression(object): params = [] else: # '=?' behaves like '=' in other cases - query, params = self.__leaf_to_sql((left, '=', right), model) + query, params = self.__leaf_to_sql( + create_substitution_leaf(eleaf, (left, '=', right), model)) elif left == 'id': query = '%s.id %s %%s' % (table_alias, operator)