[FIX] models: check harder that default value is not NULL before setting it
authorOlivier Dony <odo@openerp.com>
Thu, 24 Jul 2014 10:22:20 +0000 (12:22 +0200)
committerOlivier Dony <odo@openerp.com>
Thu, 24 Jul 2014 13:47:34 +0000 (15:47 +0200)
When computing defaults we may end up with
a falsy value that is not None (e.g. '' or False)
That value will be cast to None when being
saved in the database, depending on the column type
(e.g. saving False on a many2one actually stores NULL).

Improve the test to consider the value being written
*after* that conversion, to *really* avoid nonsensical
and expensive queries such as:

    UPDATE table set col = NULL WHERE col IS NULL;

openerp/models.py

index fffdd93..b6cad20 100644 (file)
@@ -2415,13 +2415,14 @@ class BaseModel(object):
             if column_name in defaults:
                 default = field.convert_to_write(defaults[column_name])
 
-        if default is not None:
-            _logger.debug("Table '%s': setting default value of new column %s",
-                          self._table, column_name)
-            ss = self._columns[column_name]._symbol_set
+        ss = self._columns[column_name]._symbol_set
+        store_default = ss[1](default)
+        if store_default is not None:
+            _logger.debug("Table '%s': setting default value of new column %s to %r",
+                          self._table, column_name, default)
             query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (
                 self._table, column_name, ss[0], column_name)
-            cr.execute(query, (ss[1](default),))
+            cr.execute(query, (store_default,))
             # this is a disgrace
             cr.commit()