Merge lp:~therp-nl/openupgrade-server/7.0-lp1131653_check_recursion_fix_false_positives into lp:openupgrade-server

Proposed by Stefan Rijnhart (Opener)
Status: Work in progress
Proposed branch: lp:~therp-nl/openupgrade-server/7.0-lp1131653_check_recursion_fix_false_positives
Merge into: lp:openupgrade-server
Diff against target: 47 lines (+17/-8)
1 file modified
openerp/osv/orm.py (+17/-8)
To merge this branch: bzr merge lp:~therp-nl/openupgrade-server/7.0-lp1131653_check_recursion_fix_false_positives
Reviewer Review Type Date Requested Status
Mohammad Alhashash (community) Needs Fixing
Holger Brunn (Therp) Needs Fixing
Review via email: mp+150053@code.launchpad.net

Description of the change

The bug that this branch aims to fix was discovered when testing the migration scripts for the base module.

To post a comment you must log in.
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

You can do that a lot simpler and save fetches by letting the server build a common table expression that checks for cycles:

create table rec_test (id int, parent_id int) -- that's just for the example

with recursive check_cycle(id, parent_id, is_cycle) as (select id, parent_id, False from rec_test union all select check_cycle.id, rec_test.parent_id, check_cycle.id = rec_test.parent_id from check_cycle join rec_test on check_cycle.parent_id=rec_test.id and rec_test.parent_id is not null and not is_cycle) select * from check_cycle -- that's the real thing

Filter for the ids to check in the non-recursive part, then select rows with is_cycle=True and you're done with just this statement.

review: Needs Fixing
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

PS: This fix should also go to lp:ocb-server, right?

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Amazing, thanks! I had already set this branch to 'work in progress' because my fix still had the original flaw under different circumstances. I'd like to work this out but I will not have the time now. Maybe if the overhead of the workaround (https://code.launchpad.net/~therp-nl/openupgrade-server/7.0-lp1131653_workaround/+merge/150071) starts to bother me...

As for lp:ocb-server, I cannot say that it is affected by this issue as I only ever encountered it in the OpenUpgrade process. Note that the bug was never reported before while the code has been around for some time.

Revision history for this message
Mohammad Alhashash (alhashash) wrote :
review: Needs Fixing

Unmerged revisions

4605. By Stefan Rijnhart (Opener)

[FIX] _check_recursion gives false positive if ids include a parent/child pair

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/osv/orm.py'
2--- openerp/osv/orm.py 2013-02-19 21:32:25 +0000
3+++ openerp/osv/orm.py 2013-02-22 14:20:30 +0000
4@@ -1943,7 +1943,10 @@
5 msg = "\n * ".join([r[0] for r in res])
6 msg += "\n\nEither you wrongly customized this view, or some modules bringing those views are not compatible with your current data model"
7 _logger.error(msg)
8- raise except_orm('View error', msg)
9+ # OpenUpgrade: do not raise for unknown fields, as these
10+ # can be triggered on old views that still have to be
11+ # replaced by the upgrade procedure
12+ # raise except_orm('View error', msg)
13 return arch, fields
14
15 def _get_default_form_view(self, cr, user, context=None):
16@@ -5084,18 +5087,24 @@
17
18 if not parent:
19 parent = self._parent_name
20- ids_parent = ids[:]
21- query = 'SELECT distinct "%s" FROM "%s" WHERE id IN %%s' % (parent, self._table)
22+ # OpenUpgrade: include a fix for https://bugs.launchpad.net/bugs/1131653
23+ # as this bug was discovered writing default values for new fields
24+ query = 'SELECT id, "%s" FROM "%s" WHERE id IN %%s' % (parent, self._table)
25+ ids_parent = ids
26+ hierarchy = []
27 while ids_parent:
28 ids_parent2 = []
29- for i in range(0, len(ids), cr.IN_MAX):
30+ for i in range(0, len(ids_parent), cr.IN_MAX):
31 sub_ids_parent = ids_parent[i:i+cr.IN_MAX]
32 cr.execute(query, (tuple(sub_ids_parent),))
33- ids_parent2.extend(filter(None, map(lambda x: x[0], cr.fetchall())))
34+ for row in cr.fetchall():
35+ if row[1]:
36+ if row in hierarchy:
37+ return False
38+ hierarchy.append(row)
39+ if row[1] not in ids_parent2:
40+ ids_parent2.append(row[1])
41 ids_parent = ids_parent2
42- for i in ids_parent:
43- if i in ids:
44- return False
45 return True
46
47 def _get_external_ids(self, cr, uid, ids, *args, **kwargs):

Subscribers

People subscribed via source and target branches