diff --git a/openerp/addons/test_new_api/demo_data.xml b/openerp/addons/test_new_api/demo_data.xml
index 1715b024cd7..17ac07718b3 100644
--- a/openerp/addons/test_new_api/demo_data.xml
+++ b/openerp/addons/test_new_api/demo_data.xml
@@ -28,5 +28,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openerp/addons/test_new_api/ir.model.access.csv b/openerp/addons/test_new_api/ir.model.access.csv
index 2bbd1adf12d..757e2050363 100644
--- a/openerp/addons/test_new_api/ir.model.access.csv
+++ b/openerp/addons/test_new_api/ir.model.access.csv
@@ -5,3 +5,4 @@ access_message,test_new_api_message,test_new_api.model_test_new_api_message,,1,1
access_mixed,test_new_api_mixed,test_new_api.model_test_new_api_mixed,,1,1,1,1
access_test_function_noinfiniterecursion,access_test_function_noinfiniterecursion,model_test_old_api_function_noinfiniterecursion,,1,1,1,1
access_test_function_counter,access_test_function_counter,model_test_old_api_function_counter,,1,1,1,1
+access_domain_bool,access_domain_bool,model_domain_bool,,1,1,1,1
diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py
index 173935a8985..50343b0d1fc 100644
--- a/openerp/addons/test_new_api/models.py
+++ b/openerp/addons/test_new_api/models.py
@@ -236,3 +236,11 @@ class MixedModel(models.Model):
return [(model.model, model.name)
for model in models
if not model.model.startswith('ir.')]
+
+
+class BoolModel(models.Model):
+ _name = 'domain.bool'
+
+ bool_true = fields.Boolean('b1', default=True)
+ bool_false = fields.Boolean('b2', default=False)
+ bool_undefined = fields.Boolean('b3')
diff --git a/openerp/addons/test_new_api/tests/__init__.py b/openerp/addons/test_new_api/tests/__init__.py
index f4803bd4837..1bae0b503c3 100644
--- a/openerp/addons/test_new_api/tests/__init__.py
+++ b/openerp/addons/test_new_api/tests/__init__.py
@@ -6,3 +6,4 @@ from . import test_onchange
from . import test_field_conversions
from . import test_attributes
from . import test_no_infinite_recursion
+from . import test_domain
diff --git a/openerp/addons/test_new_api/tests/test_domain.py b/openerp/addons/test_new_api/tests/test_domain.py
new file mode 100644
index 00000000000..03ee468c76d
--- /dev/null
+++ b/openerp/addons/test_new_api/tests/test_domain.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+from openerp.tests import common
+
+
+class test_domain(common.TransactionCase):
+
+ def setUp(self):
+ super(test_domain, self).setUp()
+ self.bool = self.env['domain.bool']
+
+ def test_00_test_bool_undefined(self):
+ """
+ Check that undefined/empty values in database is equal to False and different of True
+
+ """
+
+ # Add a new boolean column after that some rows/tuples has been added (with data)
+ # Existing rows/tuples will be undefined/empty
+ self.env['ir.model.fields'].create({
+ 'name': 'x_bool_new_undefined',
+ 'model_id': self.env.ref('test_new_api.model_domain_bool').id,
+ 'field_description': 'A new boolean column',
+ 'ttype': 'boolean'
+ })
+
+ self.env.ref('test_new_api.bool_3').write({'x_bool_new_undefined': True})
+ self.env.ref('test_new_api.bool_4').write({'x_bool_new_undefined': False})
+
+ model = self.bool
+ all_bool = model.search([])
+ for f in ['bool_true', 'bool_false', 'bool_undefined', 'x_bool_new_undefined']:
+ eq_1 = model.search([(f, '=', False)])
+ neq_1 = model.search([(f, '!=', True)])
+ self.assertEqual(eq_1, neq_1, '`= False` (%s) <> `!= True` (%s) ' % (len(eq_1), len(neq_1)))
+
+ eq_2 = model.search([(f, '=', True)])
+ neq_2 = model.search([(f, '!=', False)])
+ self.assertEqual(eq_2, neq_2, '`= True` (%s) <> `!= False` (%s) ' % (len(eq_2), len(neq_2)))
+
+ self.assertEqual(eq_1+eq_2, all_bool, 'True + False != all')
+ self.assertEqual(neq_1+neq_2, all_bool, 'not True + not False != all')
diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py
index ecf01d86618..ef8a40dab90 100644
--- a/openerp/osv/expression.py
+++ b/openerp/osv/expression.py
@@ -1192,7 +1192,7 @@ class expression(object):
else: # Must not happen
raise ValueError("Invalid domain term %r" % (leaf,))
- elif right == False and (left in model._columns) and model._columns[left]._type == "boolean" and (operator == '='):
+ elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '=' and right is False) or (operator == '!=' and right is True)):
query = '(%s."%s" IS NULL or %s."%s" = false )' % (table_alias, left, table_alias, left)
params = []
@@ -1200,7 +1200,7 @@ class expression(object):
query = '%s."%s" IS NULL ' % (table_alias, left)
params = []
- elif right == False and (left in model._columns) and model._columns[left]._type == "boolean" and (operator == '!='):
+ elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '!=' and right is False) or (operator == '==' and right is True)):
query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table_alias, left, table_alias, left)
params = []