Merge lp:~therp-nl/therp-backports/server-6.1-lp1062795-search_m2m_negative_gives_wrong_results into lp:therp-backports/server-6.1

Proposed by Stefan Rijnhart (Opener)
Status: Rejected
Rejected by: Stefan Rijnhart (Opener)
Proposed branch: lp:~therp-nl/therp-backports/server-6.1-lp1062795-search_m2m_negative_gives_wrong_results
Merge into: lp:therp-backports/server-6.1
Diff against target: 102 lines (+24/-25)
1 file modified
openerp/osv/expression.py (+24/-25)
To merge this branch: bzr merge lp:~therp-nl/therp-backports/server-6.1-lp1062795-search_m2m_negative_gives_wrong_results
Reviewer Review Type Date Requested Status
Therp Pending
Review via email: mp+129655@code.launchpad.net

Description of the change

To post a comment you must log in.
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

I am rejecting this as not tested well enough, because of the promotion of our branches to the community backports

Unmerged revisions

4288. By Stefan Rijnhart (Opener)

[IMP] For completeness sake, fix o2m analogously to m2m
[RFR] Some small, obvious refactorings that the fixes in this branch exposed

4287. By Stefan Rijnhart (Opener)

[FIX] Preserve negative search operator's exclusivity in m2m dotted subqueries

4286. By Stefan Rijnhart (Opener)

[FIX] Search on many2many with negative operator gives wrong results

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/osv/expression.py'
2--- openerp/osv/expression.py 2012-01-24 12:42:52 +0000
3+++ openerp/osv/expression.py 2012-10-15 11:22:23 +0000
4@@ -152,6 +152,11 @@
5 # below, this doesn't necessarily mean that any of those NEGATIVE_TERM_OPERATORS is
6 # legal in the processed term.
7 NEGATIVE_TERM_OPERATORS = ('!=', 'not like', 'not ilike', 'not in')
8+REVERSE_NEGATIVE_OPERATOR = {'!=': '=', 'not like': 'like', 'not ilike': 'ilike', 'not in': 'in'}
9+def get_ids_operator(operator):
10+ if operator in NEGATIVE_TERM_OPERATORS:
11+ return 'not in'
12+ return 'in'
13
14 TRUE_LEAF = (1, '=', 1)
15 FALSE_LEAF = (0, '=', 1)
16@@ -461,8 +466,10 @@
17 self.__exp[i] = (field_path[0], 'in', right)
18 # Making search easier when there is a left operand as field.o2m or field.m2m
19 if field._type in ['many2many', 'one2many']:
20- right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context)
21- right1 = table.search(cr, uid, [(field_path[0],'in', right)], context=dict(context, active_test=False))
22+ local_operator = REVERSE_NEGATIVE_OPERATOR.get(operator, operator)
23+ right = field_obj.search(cr, uid, [(field_path[1], local_operator, right)], context=context)
24+ ids_operator = get_ids_operator(operator)
25+ right1 = table.search(cr, uid, [(field_path[0], ids_operator, right)], context=dict(context, active_test=False))
26 self.__exp[i] = ('id', 'in', right1)
27
28 if not isinstance(field, fields.property):
29@@ -498,13 +505,11 @@
30 self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
31
32 else:
33- call_null = True
34-
35 if right is not False:
36 if isinstance(right, basestring):
37- ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, context=context, limit=None)]
38- if ids2:
39- operator = 'in'
40+ local_operator = REVERSE_NEGATIVE_OPERATOR.get(operator, operator)
41+ operator = get_ids_operator(operator)
42+ ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], local_operator, context=context, limit=None)]
43 else:
44 if not isinstance(right, list):
45 ids2 = [right]
46@@ -513,15 +518,13 @@
47 if not ids2:
48 if operator in ['like','ilike','in','=']:
49 #no result found with given search criteria
50- call_null = False
51 self.__exp[i] = FALSE_LEAF
52+ else:
53+ self.__exp[i] = TRUE_LEAF
54 else:
55- ids2 = select_from_where(cr, field._fields_id, field_obj._table, 'id', ids2, operator)
56- if ids2:
57- call_null = False
58- self.__exp[i] = ('id', 'in', ids2)
59-
60- if call_null:
61+ ids2 = select_from_where(cr, field._fields_id, field_obj._table, 'id', ids2, "in")
62+ self.__exp[i] = ('id', operator, ids2)
63+ else:
64 o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'
65 self.__exp[i] = ('id', o2m_op, select_distinct_from_where_not_null(cr, field._fields_id, field_obj._table))
66
67@@ -539,12 +542,11 @@
68 ids2 = field_obj.search(cr, uid, dom, context=context)
69 self.__exp[i] = ('id', 'in', _rec_convert(ids2))
70 else:
71- call_null_m2m = True
72 if right is not False:
73 if isinstance(right, basestring):
74- res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, context=context)]
75- if res_ids:
76- operator = 'in'
77+ local_operator = REVERSE_NEGATIVE_OPERATOR.get(operator, operator)
78+ operator = get_ids_operator(operator)
79+ res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], local_operator, context=context)]
80 else:
81 if not isinstance(right, list):
82 res_ids = [right]
83@@ -553,16 +555,13 @@
84 if not res_ids:
85 if operator in ['like','ilike','in','=']:
86 #no result found with given search criteria
87- call_null_m2m = False
88 self.__exp[i] = FALSE_LEAF
89 else:
90- operator = 'in' # operator changed because ids are directly related to main object
91+ self.__exp[i] = TRUE_LEAF
92 else:
93- call_null_m2m = False
94- m2m_op = 'not in' if operator in NEGATIVE_TERM_OPERATORS else 'in'
95- self.__exp[i] = ('id', m2m_op, select_from_where(cr, rel_id1, rel_table, rel_id2, res_ids, operator) or [0])
96-
97- if call_null_m2m:
98+ m2m_op = get_ids_operator(operator)
99+ self.__exp[i] = ('id', m2m_op, select_from_where(cr, rel_id1, rel_table, rel_id2, res_ids, "in") or [0])
100+ else:
101 m2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'
102 self.__exp[i] = ('id', m2m_op, select_distinct_from_where_not_null(cr, rel_id1, rel_table))
103

Subscribers

People subscribed via source and target branches

to all changes: