From 2c4119d1eb9e231676bf4facedf46849970b8253 Mon Sep 17 00:00:00 2001 From: John Passaro Date: Mon, 19 Sep 2016 15:43:46 -0400 Subject: [PATCH] Exclude eq and ne from associative operators The "eq" and "ne" operators are no longer part of the list of "associative" operators, while they remain considered to be "commutative". This allows an expression like ``(x == y) == z`` to be maintained at the SQL level with parenthesis. Pull request courtesy John Passaro. Fixes: #3799 Change-Id: I3759d8987b35649d7418b6524316c9e70c857e68 Pull-request: https://github.com/zzzeek/sqlalchemy/pull/308 --- doc/build/changelog/changelog_11.rst | 10 ++++++++++ lib/sqlalchemy/sql/operators.py | 2 +- test/sql/test_operators.py | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index a097034891..4693eda29b 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -21,6 +21,16 @@ .. changelog:: :version: 1.1.0 + .. change:: + :tags: bug, sql + :tickets: 3799 + + The "eq" and "ne" operators are no longer part of the list of + "associative" operators, while they remain considered to be + "commutative". This allows an expression like ``(x == y) == z`` + to be maintained at the SQL level with parenthesis. Pull request + courtesy John Passaro. + .. change:: :tags: bug, orm :tickets: 3788 diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index bf470710db..1426066804 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -917,7 +917,7 @@ def mirror(op): return _mirror.get(op, op) -_associative = _commutative.union([concat_op, and_, or_]) +_associative = _commutative.union([concat_op, and_, or_]).difference([eq, ne]) _natural_self_precedent = _associative.union([ getitem, json_getitem_op, json_path_getitem_op]) diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index b6e80de4ba..99f8a10ca3 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -1538,6 +1538,14 @@ class OperatorAssociativityTest(fixtures.TestBase, testing.AssertsCompiledSQL): f = column('f') self.assert_compile(f / (f / (f - f)), "f / (f / (f - f))") + def test_associativity_22(self): + f = column('f') + self.assert_compile((f==f) == f, '(f = f) = f') + + def test_associativity_23(self): + f = column('f') + self.assert_compile((f!=f) != f, '(f != f) != f') + class IsDistinctFromTest(fixtures.TestBase, testing.AssertsCompiledSQL): __dialect__ = 'default' -- 2.47.2