[IMP] expression: some more tests pass with the correct semantic.

bzr revid: vmt@openerp.com-20110810143838-l5ujglk5w85mchv1
This commit is contained in:
Vo Minh Thu 2011-08-10 16:38:38 +02:00
parent 19a21de5e1
commit 5de1e1a367
2 changed files with 63 additions and 13 deletions

View File

@ -240,32 +240,40 @@
assert res_2 == with_parent
assert res_3 == partner_ids
assert res_4 == with_parent
print ">>> ----------"
# The results of these queries, when combined with queries 0..4 must
# give the whole set of ids.
res_5 = self.search(cr, uid, [('parent_id', 'like', 'probably_unexisting_name')])
res_5.sort()
res_6 = self.search(cr, uid, [('parent_id', 'in', [max_partner_id + 1])])
res_6.sort()
res_7 = self.search(cr, uid, [('parent_id', 'in', False)])
res_7.sort()
res_8 = self.search(cr, uid, [('parent_id', 'in', [])])
res_8.sort()
res_9 = self.search(cr, uid, [('parent_id', 'in', [False])])
print ">>> 5:", res_5
print ">>> 6:", res_6
print ">>> 7:", res_7
print ">>> 8:", res_8
print ">>> 9:", res_9
print ">>> ----------"
res_9.sort()
assert res_5 == []
assert res_6 == []
assert res_7 == without_parent
assert res_8 == []
assert res_9 == without_parent
# These queries must return exactly the results than the queries 0..4,
# i.e. not ... in ... must be the same as ... not in ... .
res_10 = self.search(cr, uid, ['!', ('parent_id', 'like', 'probably_unexisting_name')])
res_10.sort()
res_11 = self.search(cr, uid, ['!', ('parent_id', 'in', [max_partner_id + 1])])
res_11.sort()
res_12 = self.search(cr, uid, ['!', ('parent_id', 'in', False)])
res_12.sort()
res_13 = self.search(cr, uid, ['!', ('parent_id', 'in', [])])
res_13.sort()
res_14 = self.search(cr, uid, ['!', ('parent_id', 'in', [False])])
print ">>> 10:", res_10
print ">>> 11:", res_11
print ">>> 12:", res_12
print ">>> 13:", res_13
print ">>> 14:", res_14
res_14.sort()
assert res_0 == res_10
assert res_1 == res_11
assert res_2 == res_12
assert res_3 == res_13
assert res_4 == res_14
# Testing many2one field is not enough, a regular char field is tested
# with in [] and must not return any result.

View File

@ -128,6 +128,48 @@ def normalize_leaf(left, operator, right):
operator = 'in' if operator == '=' else 'not in'
return left, operator, right
def distribute_not(domain):
""" Distribute the '!' operator on a normalized domain.
"""
def negate(leaf):
left, operator, right = leaf
mapping = {
'<': '>=',
'>': '<=',
'<=': '>',
'>=': '<',
'=': '!=',
'!=': '=',
}
if operator in ('in', 'like', 'ilike'):
operator = 'not ' + operator
return [(left, operator, right)]
if operator in ('not in', 'not like', 'not ilike'):
operator = operator[4:]
return [(left, operator, right)]
if operator in mapping:
operator = mapping[operator]
return [(left, operator, right)]
return ['!', (left, operator, right)]
def distribute(domain):
if is_leaf(domain[0]):
return negate(domain[0]), domain[1:]
if domain[0] == '&':
done1, todo1 = distribute(domain[1:])
done2, todo2 = distribute(todo1)
return ['|'] + done1 + done2, todo2
if domain[0] == '|':
done1, todo1 = distribute(domain[1:])
done2, todo2 = distribute(todo1)
return ['&'] + done1 + done2, todo2
if not domain:
return []
if domain[0] != '!':
return [domain[0]] + distribute_not(domain[1:])
if domain[0] == '!':
done, todo = distribute(domain[1:])
return done + distribute_not(todo)
def select_from_where(cr, s, f, w, ids, op):
# todo: merge into parent query as sub-query
res = []
@ -162,7 +204,7 @@ class expression(object):
self.__joins = []
self.__main_table = None # 'root' table. set by parse()
# assign self.__exp with the normalized, parsed domain.
self.parse(cr, uid, normalize(exp), table, context)
self.parse(cr, uid, distribute_not(normalize(exp)), table, context)
# TODO used only for osv_memory
@property