]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Deliver straight BinaryExpr w/ no negate for any() / all()
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Aug 2020 18:17:06 +0000 (14:17 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Aug 2020 18:18:02 +0000 (14:18 -0400)
Adjusted the :meth:`_types.ARRAY.Comparator.any` and
:meth:`_types.ARRAY.Comparator.all` methods to implement a straight "NOT"
operation for negation, rather than negating the comparison operator.

Fixes: #5518
Change-Id: I87ee9278c321aafe51a679fcfcbb5fbb11307fda

doc/build/changelog/unreleased_13/5518.rst [new file with mode: 0644]
lib/sqlalchemy/sql/sqltypes.py
test/dialect/postgresql/test_compiler.py
test/sql/test_operators.py

diff --git a/doc/build/changelog/unreleased_13/5518.rst b/doc/build/changelog/unreleased_13/5518.rst
new file mode 100644 (file)
index 0000000..1cd2a25
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, postgresql
+    :tickets: 5518
+
+    Adjusted the :meth:`_types.ARRAY.Comparator.any` and
+    :meth:`_types.ARRAY.Comparator.all` methods to implement a straight "NOT"
+    operation for negation, rather than negating the comparison operator.
\ No newline at end of file
index 14ddedaeca5d67aadaca0c1707e396017802f9c4..fd85d6d303ed777f8bdd986a5ed1d8faea02f135 100644 (file)
@@ -2699,9 +2699,13 @@ class ARRAY(SchemaEventTarget, Indexable, Concatenable, TypeEngine):
             """
             elements = util.preloaded.sql_elements
             operator = operator if operator else operators.eq
-            return operator(
+
+            # send plain BinaryExpression so that negate remains at None,
+            # leading to NOT expr for negation.
+            return elements.BinaryExpression(
                 coercions.expect(roles.ExpressionElementRole, other),
                 elements.CollectionAggregate._create_any(self.expr),
+                operator,
             )
 
         @util.preload_module("sqlalchemy.sql.elements")
@@ -2735,9 +2739,13 @@ class ARRAY(SchemaEventTarget, Indexable, Concatenable, TypeEngine):
             """
             elements = util.preloaded.sql_elements
             operator = operator if operator else operators.eq
-            return operator(
+
+            # send plain BinaryExpression so that negate remains at None,
+            # leading to NOT expr for negation.
+            return elements.BinaryExpression(
                 coercions.expect(roles.ExpressionElementRole, other),
                 elements.CollectionAggregate._create_all(self.expr),
+                operator,
             )
 
     comparator_factory = Comparator
index 20732067dcba1988da9ff80bbe9e5d94021e73ae..ce285007f75169a27eff6e41987e741b7d117657 100644 (file)
@@ -1234,6 +1234,27 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "%(param_1)s = ANY (x)",
             checkparams={"param_1": 4},
         )
+
+        self.assert_compile(
+            c.any(5), "%(param_1)s = ANY (x)", checkparams={"param_1": 5},
+        )
+
+        self.assert_compile(
+            ~c.any(5),
+            "NOT (%(param_1)s = ANY (x))",
+            checkparams={"param_1": 5},
+        )
+
+        self.assert_compile(
+            c.all(5), "%(param_1)s = ALL (x)", checkparams={"param_1": 5},
+        )
+
+        self.assert_compile(
+            ~c.all(5),
+            "NOT (%(param_1)s = ALL (x))",
+            checkparams={"param_1": 5},
+        )
+
         self.assert_compile(
             c.any(5, operator=operators.ne),
             "%(param_1)s != ANY (x)",
index e5835a7498f1d6cf983f8369df58df8bff56da76..fcf40ebbd22b71f84b08618839c01511353ea94f 100644 (file)
@@ -3045,6 +3045,15 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             checkparams={"param_1": 5},
         )
 
+    def test_any_array_comparator_negate_accessor(self, t_fixture):
+        t = t_fixture
+
+        self.assert_compile(
+            ~t.c.arrval.any(5, operator.gt),
+            "NOT (:param_1 > ANY (tab1.arrval))",
+            checkparams={"param_1": 5},
+        )
+
     def test_all_array_comparator_accessor(self, t_fixture):
         t = t_fixture
 
@@ -3054,6 +3063,15 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             checkparams={"param_1": 5},
         )
 
+    def test_all_array_comparator_negate_accessor(self, t_fixture):
+        t = t_fixture
+
+        self.assert_compile(
+            ~t.c.arrval.all(5, operator.gt),
+            "NOT (:param_1 > ALL (tab1.arrval))",
+            checkparams={"param_1": 5},
+        )
+
     def test_any_array_expression(self, t_fixture):
         t = t_fixture