[6.0][5.0] ORM bug : function field with type one2many = "ir_translation polluted and duplicated function dead"
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
Odoo Server (MOVED TO GITHUB) | Status tracked in Trunk | |||||
5.0 |
Won't Fix
|
Undecided
|
Unassigned | |||
6.0 |
Won't Fix
|
Undecided
|
Unassigned | |||
Trunk |
Fix Committed
|
Low
|
OpenERP's Framework R&D |
Bug Description
Hi !
I found a bug in the ORM on V5 and also on V6. To reproduce it, you need to install a module which has a function field with the type "one2many" ; this is the case of magentoerpconnect for example.
Scenario of the bug :
1) you must have two or more languages
2) you must have an object with a function field with the type "one2many" (in magentoerpconnect, the object sale_shop has a function field "exportable_
3) be sure that this field returns some ids
4) try to duplicate the object (in our example : try to duplicate a sale_shop)
5) you get the bug !
openerp V6 error:
[2011-01-20 09:47:53,
Traceback (most recent call last):
File "/home/
return f(self, dbname, *args, **kwargs)
File "/home/
res = self.execute_cr(cr, uid, obj, method, *args, **kw)
File "/home/
return getattr(object, method)(cr, uid, *args, **kw)
File "/home/
self.
File "/home/
target_
File "/home/
old_record, new_record = self.read(cr, uid, [old_id, new_id], [field_name], context=context)
ValueError: need more than 1 value to unpack
openerp V5 error:
Traceback (most recent call last):
File "/home/
result = LocalService(
File "/home/
return getattr(self, method)(*params)
File "/home/
res = service.execute(db, uid, object, method, *args)
File "/home/
return f(self, dbname, *args, **kwargs)
File "/home/
res = pool.execute_cr(cr, uid, obj, method, *args, **kw)
File "/home/
return getattr(object, method)(cr, uid, *args, **kw)
File "/home/
for record in translation_
File "/home/
if field_def['type'] in ('one2one', 'one2many'):
File "/home/
ValueError: need more than 1 value to unpack
And now the ugly part ! By chance, Openerp doesn't succeed in copying the sale shop because the product is linked with bom_ids and in this case bom_ids=False ; therefore, the copy of the translation fails.
But, for the OpenERP install at Anevia, a more simple scenario : in one of the Anevia-specific modules, we added a field origin_country_ids on the picking which will return all country_id of the products present in the move lines. Country_id on the product is a translatable field.
In this case, Openerp succeeds in copying the translation of the country and this will start a TIME BOMB for your openerp server and your database (more details below).
OPENERP SHOULDN'T COPY THE DATA OF A FUNCTION FIELD! This must be fixed.
First bug (only present on V5) :
When you duplicate a sale_order, OpenERP will duplicate all the related sale order lines. The same way, when Anevia duplicates a picking, Openerp will try to duplicate all the country objects present in origin_country_ids ; but, by chance, as there is no inverse funtion, it can't!!
So the following patch will prevent the data to be copied in this scenario (this bug is already fixed in V6, but still unfixed in V5)
@@ -3132,7 +3132,7 @@
if f in default:
- elif ftype == 'function':
+ elif '_fnct' in dir(self.
elif ftype == 'many2one':
In the code, the "ftype" variable will only contain "one2many" or "text" or "boolean" or ... but it will never contain "function" even if it is a function field.
Second bug (present in V5 and V6), which is the dangerous one : Openerp will copy all translations linked to the object selected by the function field (in our case openerp will duplicate all country translation ie : name)
So here is the TIME BOMB :
when you duplicate a picking for the first time : the table ir_translation will have 2 identical translations for the countries
when you duplicate a picking again with the same origin_coutrny_ids : the table ir_translation will have 4 identical translations for the countries
when you duplicate a picking again with the same origin_coutrny_ids : the table ir_translation will have 8 identical translations for the countries
when you duplicate a picking again with the same origin_coutrny_ids : the table ir_translation will have 16 identical translations for the countries
when you duplicate a picking again with the same origin_coutrny_ids : the table ir_translation will have 32 identical translations for the countries
..
..
..
..
after 20 duplicates : the table ir_translation will have 1 048 576 identical translations for the countries ! So, the next duplicate will copy 1 048 576 entries in the table ir_translation... so the OpenERP server and postgres database will eat all your CPU during a very very long time ! This is why this bug is a time bomb : you only start to experience it after some time of real-world use of your OpenERP.
This is the patch for this second bug :
@@ -3175,7 +3175,7 @@
for field_name, field_def in fields.items():
# we must recursively copy the translations for o2o and o2m
- if field_def['type'] in ('one2one', 'one2many'):
+ if field_def['type'] in ('one2one', 'one2many') and not '_fnct' in dir(self.
# here we rely on the order of the ids to match the translations
By the way, it would be good to add a constraint on the table ir_translation ; indeed, a field should only have one translation per object and per language. Adding a constraint would make sure that the ir_translation table never gets "polluted".
These 2 patches are already in production on Anevia's OpenERP v5 server.
After applying the patch, users should also clean-up the ir_translation table of their OpenERP database.
Best regards
Related branches
- Naresh(OpenERP) (community): Needs Fixing
- Vo Minh Thu: Pending requested
-
Diff: 56 lines (+28/-11)1 file modifiedopenerp/osv/orm.py (+28/-11)
Changed in openobject-server: | |
importance: | Undecided → Critical |
summary: |
- [6.0][5.0] ORM bug : function field with type one2many = TIME BOMB + [6.0][5.0] ORM bug : function field with type one2many = "ir_translation + polluted and duplicated function dead" |
There is no "time bomb" string in the code. Perhaps you are talking about another project.