diff --git a/clickhouse_orm/query.py b/clickhouse_orm/query.py index 7287350..e0ab42e 100644 --- a/clickhouse_orm/query.py +++ b/clickhouse_orm/query.py @@ -209,21 +209,18 @@ class Q(object): Checks if there are any conditions in Q object Returns: Boolean """ - return not bool(self._conds or self._children) + return not (self._conds or self._children) @classmethod def _construct_from(cls, l_child, r_child, mode): - if mode == l_child._mode: + if mode == l_child._mode and not l_child._negate: q = deepcopy(l_child) q._children.append(deepcopy(r_child)) - elif mode == r_child._mode: - q = deepcopy(r_child) - q._children.append(deepcopy(l_child)) + else: - # Different modes q = cls() q._children = [l_child, r_child] - q._mode = mode # AND/OR + q._mode = mode return q diff --git a/tests/test_querysets.py b/tests/test_querysets.py index 575435e..10ec863 100644 --- a/tests/test_querysets.py +++ b/tests/test_querysets.py @@ -6,7 +6,7 @@ from logging import getLogger from clickhouse_orm.database import Database from clickhouse_orm.engines import CollapsingMergeTree, Memory, MergeTree -from clickhouse_orm.fields import DateField, DateTimeField, Enum8Field, Int8Field, Int32Field, UInt64Field +from clickhouse_orm.fields import DateField, DateTimeField, Enum8Field, Int8Field, Int32Field, StringField, UInt64Field from clickhouse_orm.funcs import F from clickhouse_orm.models import Model from clickhouse_orm.query import Q @@ -568,10 +568,22 @@ class AggregateTestCase(TestCaseWithData): limited_qs = qs.limit_by((6, 3), "height") self.assertEqual([p.first_name for p in limited_qs[:3]], ["Norman", "Octavius", "Oliver"]) + def test_boolean_logic(self): + p = ~Q(x="eggs") + q = Q(y="spam") + r = p & q + + self.assertEqual(r.to_sql(StringyModel), "(NOT (x = 'eggs')) AND (y = 'spam')") + Color = Enum("Color", u"red blue green yellow brown white black") +class StringyModel(Model): + x = StringField() + y = StringField() + + class SampleModel(Model): timestamp = DateTimeField()