From: Mike Bayer Date: Sat, 20 Sep 2025 16:22:48 +0000 (-0400) Subject: deprecate ARRAY.any(), ARRAY.all(), postgresql.Any(), postgresql.All() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=efd49a19a4a8a7e5468939c92114f6e31328afb6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git deprecate ARRAY.any(), ARRAY.all(), postgresql.Any(), postgresql.All() The :meth:`_types.ARRAY.Comparator.any` and :meth:`_types.ARRAY.Comparator.all` methods for the :class:`_types.ARRAY` type are now deprecated for removal; these two methods along with :func:`_postgresql.Any` and :func:`_postgresql.All` have been legacy for some time as they are superseded by the :func:`_sql.any_` and :func:`_sql.all_` functions, which feature more intutive use. Fixes: #10821 Change-Id: I8eb3bbcb98af4ee60a21767dc3bdac771cbc0b4c --- diff --git a/doc/build/changelog/unreleased_21/10821.rst b/doc/build/changelog/unreleased_21/10821.rst new file mode 100644 index 0000000000..39e7329303 --- /dev/null +++ b/doc/build/changelog/unreleased_21/10821.rst @@ -0,0 +1,11 @@ +.. change:: + :tags: change, postgresql + :tickets: 10821 + + The :meth:`_types.ARRAY.Comparator.any` and + :meth:`_types.ARRAY.Comparator.all` methods for the :class:`_types.ARRAY` + type are now deprecated for removal; these two methods along with + :func:`_postgresql.Any` and :func:`_postgresql.All` have been legacy for + some time as they are superseded by the :func:`_sql.any_` and + :func:`_sql.all_` functions, which feature more intutive use. + diff --git a/lib/sqlalchemy/dialects/postgresql/array.py b/lib/sqlalchemy/dialects/postgresql/array.py index a3ac4d8fd4..7835dd5bd1 100644 --- a/lib/sqlalchemy/dialects/postgresql/array.py +++ b/lib/sqlalchemy/dialects/postgresql/array.py @@ -55,6 +55,15 @@ def Any( """A synonym for the ARRAY-level :meth:`.ARRAY.Comparator.any` method. See that method for details. + .. deprecated:: 2.1 + + The :meth:`_types.ARRAY.Comparator.any` and + :meth:`_types.ARRAY.Comparator.all` methods for arrays are deprecated + for removal, along with the PG-specific :func:`_postgresql.Any` and + :func:`_postgresql.All` functions. See :func:`_sql.any_` and + :func:`_sql.all_` functions for modern use. + + """ return arrexpr.any(other, operator) # type: ignore[no-any-return, union-attr] # noqa: E501 @@ -68,6 +77,14 @@ def All( """A synonym for the ARRAY-level :meth:`.ARRAY.Comparator.all` method. See that method for details. + .. deprecated:: 2.1 + + The :meth:`_types.ARRAY.Comparator.any` and + :meth:`_types.ARRAY.Comparator.all` methods for arrays are deprecated + for removal, along with the PG-specific :func:`_postgresql.Any` and + :func:`_postgresql.All` functions. See :func:`_sql.any_` and + :func:`_sql.all_` functions for modern use. + """ return arrexpr.all(other, operator) # type: ignore[no-any-return, union-attr] # noqa: E501 diff --git a/lib/sqlalchemy/sql/_elements_constructors.py b/lib/sqlalchemy/sql/_elements_constructors.py index cc2f8201cc..2b37c12d27 100644 --- a/lib/sqlalchemy/sql/_elements_constructors.py +++ b/lib/sqlalchemy/sql/_elements_constructors.py @@ -99,11 +99,8 @@ def all_(expr: _ColumnExpressionArgument[_T]) -> CollectionAggregate[bool]: # would render 'NULL = ALL(somearray)' all_(mytable.c.somearray) == None - .. versionchanged:: 1.4.26 repaired the use of any_() / all_() - comparing to NULL on the right side to be flipped to the left. - The column-level :meth:`_sql.ColumnElement.all_` method (not to be - confused with :class:`_types.ARRAY` level + confused with the deprecated :class:`_types.ARRAY` level :meth:`_types.ARRAY.Comparator.all`) is shorthand for ``all_(col)``:: @@ -285,11 +282,8 @@ def any_(expr: _ColumnExpressionArgument[_T]) -> CollectionAggregate[bool]: # would render 'NULL = ANY(somearray)' any_(mytable.c.somearray) == None - .. versionchanged:: 1.4.26 repaired the use of any_() / all_() - comparing to NULL on the right side to be flipped to the left. - The column-level :meth:`_sql.ColumnElement.any_` method (not to be - confused with :class:`_types.ARRAY` level + confused with the deprecated :class:`_types.ARRAY` level :meth:`_types.ARRAY.Comparator.any`) is shorthand for ``any_(col)``:: diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 33d749339c..449eadda45 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -3116,18 +3116,21 @@ class ARRAY( "ARRAY type; please use the dialect-specific ARRAY type" ) + @util.deprecated( + "2.1", + message="The :meth:`_types.ARRAY.Comparator.any` and " + ":meth:`_types.ARRAY.Comparator.all` methods for arrays are " + "deprecated for removal, along with the PG-specific " + ":func:`_postgresql.Any` and " + ":func:`_postgresql.All` functions. See :func:`_sql.any_` and " + ":func:`_sql.all_` functions for modern use.", + ) @util.preload_module("sqlalchemy.sql.elements") def any( self, other: Any, operator: Optional[OperatorType] = None ) -> ColumnElement[bool]: """Return ``other operator ANY (array)`` clause. - .. legacy:: This method is an :class:`_types.ARRAY` - specific - construct that is now superseded by the :func:`_sql.any_` - function, which features a different calling style. The - :func:`_sql.any_` function is also mirrored at the method level - via the :meth:`_sql.ColumnOperators.any_` method. - Usage of array-specific :meth:`_types.ARRAY.Comparator.any` is as follows:: @@ -3165,18 +3168,21 @@ class ARRAY( ), ) + @util.deprecated( + "2.1", + message="The :meth:`_types.ARRAY.Comparator.any` and " + ":meth:`_types.ARRAY.Comparator.all` methods for arrays are " + "deprecated for removal, along with the PG-specific " + ":func:`_postgresql.Any` and " + ":func:`_postgresql.All` functions. See :func:`_sql.any_` and " + ":func:`_sql.all_` functions for modern use.", + ) @util.preload_module("sqlalchemy.sql.elements") def all( self, other: Any, operator: Optional[OperatorType] = None ) -> ColumnElement[bool]: """Return ``other operator ALL (array)`` clause. - .. legacy:: This method is an :class:`_types.ARRAY` - specific - construct that is now superseded by the :func:`_sql.all_` - function, which features a different calling style. The - :func:`_sql.all_` function is also mirrored at the method level - via the :meth:`_sql.ColumnOperators.all_` method. - Usage of array-specific :meth:`_types.ARRAY.Comparator.all` is as follows:: diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py index d1b753d54f..f91453c3f4 100644 --- a/test/dialect/postgresql/test_compiler.py +++ b/test/dialect/postgresql/test_compiler.py @@ -1,7 +1,9 @@ import random import re +from sqlalchemy import all_ from sqlalchemy import and_ +from sqlalchemy import any_ from sqlalchemy import BigInteger from sqlalchemy import bindparam from sqlalchemy import case @@ -1853,6 +1855,16 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): x, """SELECT pg_table.col1, pg_table."variadic" FROM pg_table""" ) + def _array_any_deprecation(self): + return testing.expect_deprecated( + r"The ARRAY.Comparator.any\(\) and " + r"ARRAY.Comparator.all\(\) methods " + r"for arrays are deprecated for removal, along with the " + r"PG-specific Any\(\) " + r"and All\(\) functions. See any_\(\) and all_\(\) functions for " + "modern use. " + ) + def test_array(self): c = Column("x", postgresql.ARRAY(Integer)) @@ -1899,52 +1911,135 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): checkparams={"x_1": [3]}, dialect=PGDialect_psycopg2(), ) + + def test_array_modern_any_all(self): + c = Column("x", postgresql.ARRAY(Integer)) + self.assert_compile( - postgresql.Any(4, c), - "%(x_1)s = ANY (x)", - checkparams={"x_1": 4}, + 4 == c.any_(), + "%(param_1)s = ANY (x)", + checkparams={"param_1": 4}, ) self.assert_compile( - c.any(5), - "%(x_1)s = ANY (x)", - checkparams={"x_1": 5}, + 5 == any_(c), + "%(param_1)s = ANY (x)", + checkparams={"param_1": 5}, ) self.assert_compile( - ~c.any(5), - "NOT (%(x_1)s = ANY (x))", - checkparams={"x_1": 5}, + ~(c.any_() == 5), + "NOT (%(param_1)s = ANY (x))", + checkparams={"param_1": 5}, ) self.assert_compile( - c.all(5), - "%(x_1)s = ALL (x)", - checkparams={"x_1": 5}, + ~(5 == c.any_()), + "NOT (%(param_1)s = ANY (x))", + checkparams={"param_1": 5}, ) self.assert_compile( - ~c.all(5), - "NOT (%(x_1)s = ALL (x))", - checkparams={"x_1": 5}, + 5 != any_(c), + "%(param_1)s != ANY (x)", + checkparams={"param_1": 5}, ) self.assert_compile( - c.any(5, operator=operators.ne), - "%(x_1)s != ANY (x)", - checkparams={"x_1": 5}, + 6 > all_(c), + "%(param_1)s > ALL (x)", + checkparams={"param_1": 6}, ) + self.assert_compile( - postgresql.All(6, c, operator=operators.gt), - "%(x_1)s > ALL (x)", - checkparams={"x_1": 6}, + 7 < all_(c), + "%(param_1)s < ALL (x)", + checkparams={"param_1": 7}, ) + self.assert_compile( - c.all(7, operator=operators.lt), - "%(x_1)s < ALL (x)", - checkparams={"x_1": 7}, + c.all_() == 5, + "%(param_1)s = ALL (x)", + checkparams={"param_1": 5}, ) + self.assert_compile( + 5 == c.all_(), + "%(param_1)s = ALL (x)", + checkparams={"param_1": 5}, + ) + + self.assert_compile( + ~(5 == all_(c)), + "NOT (%(param_1)s = ALL (x))", + checkparams={"param_1": 5}, + ) + + self.assert_compile( + ~(all_(c) == 5), + "NOT (%(param_1)s = ALL (x))", + checkparams={"param_1": 5}, + ) + + def test_array_deprecated_any_all(self): + c = Column("x", postgresql.ARRAY(Integer)) + + with self._array_any_deprecation(): + self.assert_compile( + postgresql.Any(4, c), + "%(x_1)s = ANY (x)", + checkparams={"x_1": 4}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + c.any(5), + "%(x_1)s = ANY (x)", + checkparams={"x_1": 5}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + ~c.any(5), + "NOT (%(x_1)s = ANY (x))", + checkparams={"x_1": 5}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + c.any(5, operator=operators.ne), + "%(x_1)s != ANY (x)", + checkparams={"x_1": 5}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + postgresql.All(6, c, operator=operators.gt), + "%(x_1)s > ALL (x)", + checkparams={"x_1": 6}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + c.all(7, operator=operators.lt), + "%(x_1)s < ALL (x)", + checkparams={"x_1": 7}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + c.all(5), + "%(x_1)s = ALL (x)", + checkparams={"x_1": 5}, + ) + + with self._array_any_deprecation(): + self.assert_compile( + ~c.all(5), + "NOT (%(x_1)s = ALL (x))", + checkparams={"x_1": 5}, + ) + @testing.combinations( (lambda c: c.overlap, "&&"), (lambda c: c.contains, "@>"), diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index 5cacf015ec..db949ae828 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -106,6 +106,17 @@ from sqlalchemy.types import UserDefinedType from ...engine.test_ddlevents import DDLEventWCreateHarness +def _array_any_deprecation(): + return testing.expect_deprecated( + r"The ARRAY.Comparator.any\(\) and " + r"ARRAY.Comparator.all\(\) methods " + r"for arrays are deprecated for removal, along with the " + r"PG-specific Any\(\) " + r"and All\(\) functions. See any_\(\) and all_\(\) functions for " + "modern use. " + ) + + class MiscTypesTest(AssertsCompiledSQL, fixtures.TestBase): __dialect__ = postgresql.dialect() @@ -1942,21 +1953,25 @@ class ArrayTest(AssertsCompiledSQL, fixtures.TestBase): checkparams={"x_1": 3}, ) - def test_array_any(self): + def test_array_deprecated_any(self): col = column("x", postgresql.ARRAY(Integer)) - self.assert_compile( - select(col.any(7, operator=operators.lt)), - "SELECT %(x_1)s < ANY (x) AS anon_1", - checkparams={"x_1": 7}, - ) - def test_array_all(self): + with _array_any_deprecation(): + self.assert_compile( + select(col.any(7, operator=operators.lt)), + "SELECT %(x_1)s < ANY (x) AS anon_1", + checkparams={"x_1": 7}, + ) + + def test_array_deprecated_all(self): col = column("x", postgresql.ARRAY(Integer)) - self.assert_compile( - select(col.all(7, operator=operators.lt)), - "SELECT %(x_1)s < ALL (x) AS anon_1", - checkparams={"x_1": 7}, - ) + + with _array_any_deprecation(): + self.assert_compile( + select(col.all(7, operator=operators.lt)), + "SELECT %(x_1)s < ALL (x) AS anon_1", + checkparams={"x_1": 7}, + ) def test_array_contains(self): col = column("x", postgresql.ARRAY(Integer)) @@ -2562,9 +2577,7 @@ class ArrayRoundTripTest: connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6])) eq_( connection.scalar( - select(arrtable.c.intarr).where( - postgresql.Any(5, arrtable.c.intarr) - ) + select(arrtable.c.intarr).where(5 == any_(arrtable.c.intarr)) ), [4, 5, 6], ) @@ -2572,15 +2585,44 @@ class ArrayRoundTripTest: def test_array_all_exec(self, connection): arrtable = self.tables.arrtable connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6])) + eq_( connection.scalar( - select(arrtable.c.intarr).where( - arrtable.c.intarr.all(4, operator=operators.le) - ) + select(arrtable.c.intarr).where(4 <= all_(arrtable.c.intarr)) ), [4, 5, 6], ) + def test_array_any_deprecated_exec(self, connection): + arrtable = self.tables.arrtable + connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6])) + + with _array_any_deprecation(): + eq_( + connection.scalar( + select(arrtable.c.intarr).where( + postgresql.Any(5, arrtable.c.intarr) + ) + ), + [4, 5, 6], + ) + + def test_array_all_deprecated_exec(self, connection): + arrtable = self.tables.arrtable + connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6])) + + with _array_any_deprecation(): + eq_( + connection.scalar( + select(arrtable.c.intarr).where( + postgresql.All( + 4, arrtable.c.intarr, operator=operators.le + ) + ) + ), + [4, 5, 6], + ) + def test_tuple_flag(self, connection, metadata): t1 = Table( "t1", @@ -3255,21 +3297,22 @@ class ArrayEnum(fixtures.TestBase): @_enum_combinations @testing.combinations("all", "any", argnames="fn") - def test_any_all_legacy_roundtrip( + def test_any_all_deprecated_roundtrip( self, array_of_enum_fixture, connection, array_cls, enum_cls, fn ): """test #6515""" tbl, MyEnum = array_of_enum_fixture(array_cls, enum_cls) - if fn == "all": - expr = tbl.c.pyenum_col.all(MyEnum.b) - result = [([MyEnum.b],)] - elif fn == "any": - expr = tbl.c.pyenum_col.any(MyEnum.b) - result = [([MyEnum.a, MyEnum.b],), ([MyEnum.b],)] - else: - assert False + with _array_any_deprecation(): + if fn == "all": + expr = tbl.c.pyenum_col.all(MyEnum.b) + result = [([MyEnum.b],)] + elif fn == "any": + expr = tbl.c.pyenum_col.any(MyEnum.b) + result = [([MyEnum.a, MyEnum.b],), ([MyEnum.b],)] + else: + assert False sel = select(tbl.c.pyenum_col).where(expr).order_by(tbl.c.id) eq_(connection.execute(sel).fetchall(), result) diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index 51046d2458..8de22b89db 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -4929,40 +4929,6 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL): # of String assert isinstance(boolean_expr.left.type, expected_type_affinity) - @testing.variation("operator", ["any", "all"]) - @testing.variation("datatype", ["array", "arraystring", "arrayenum"]) - def test_what_type_is_legacy_any_all( - self, - datatype: testing.Variation, - t_fixture, - operator: testing.Variation, - ): - if datatype.array: - col = t_fixture.c.arrval - value = 25 - expected_type_affinity = Integer - elif datatype.arraystring: - col = t_fixture.c.arrstring - value = "a string" - expected_type_affinity = String - elif datatype.arrayenum: - col = t_fixture.c.arrenum - value = MyEnum.TWO - expected_type_affinity = Enum - else: - datatype.fail() - - if operator.any: - boolean_expr = col.any(value) - elif operator.all: - boolean_expr = col.all(value) - else: - operator.fail() - - # using isinstance so things work out for Enum which has type affinity - # of String - assert isinstance(boolean_expr.left.type, expected_type_affinity) - @testing.fixture( params=[ ("ANY", any_), @@ -4974,17 +4940,6 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL): def any_all_operators(self, request): return request.param - # test legacy array any() / all(). these are superseded by the - # any_() / all_() versions - @testing.fixture( - params=[ - ("ANY", lambda x, *o: x.any(*o)), - ("ALL", lambda x, *o: x.all(*o)), - ] - ) - def legacy_any_all_operators(self, request): - return request.param - def test_array(self, t_fixture, any_all_operators): t = t_fixture op, fn = any_all_operators @@ -5058,41 +5013,6 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL): t.c.data + fn(t.c.arrval), f"tab1.data + {op} (tab1.arrval)" ) - def test_bindparam_coercion(self, t_fixture, legacy_any_all_operators): - """test #7979""" - t = t_fixture - op, fn = legacy_any_all_operators - - expr = fn(t.c.arrval, bindparam("param")) - expected = f"%(param)s = {op} (tab1.arrval)" - is_(expr.left.type._type_affinity, Integer) - - self.assert_compile(expr, expected, dialect="postgresql") - - def test_array_comparator_accessor( - self, t_fixture, legacy_any_all_operators - ): - t = t_fixture - op, fn = legacy_any_all_operators - - self.assert_compile( - fn(t.c.arrval, 5, operator.gt), - f":arrval_1 > {op} (tab1.arrval)", - checkparams={"arrval_1": 5}, - ) - - def test_array_comparator_negate_accessor( - self, t_fixture, legacy_any_all_operators - ): - t = t_fixture - op, fn = legacy_any_all_operators - - self.assert_compile( - ~fn(t.c.arrval, 5, operator.gt), - f"NOT (:arrval_1 > {op} (tab1.arrval))", - checkparams={"arrval_1": 5}, - ) - def test_array_expression(self, t_fixture, any_all_operators): t = t_fixture op, fn = any_all_operators @@ -5145,6 +5065,118 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL): fn(values(t.c.data).data([(1,), (42,)])) +class DeprecatedAnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL): + __dialect__ = "default" + + @testing.fixture + def t_fixture(self): + m = MetaData() + + t = Table( + "tab1", + m, + Column("arrval", ARRAY(Integer)), + Column("arrenum", ARRAY(Enum(MyEnum))), + Column("arrstring", ARRAY(String)), + Column("data", Integer), + ) + return t + + # test legacy array any() / all(). these are superseded by the + # any_() / all_() versions + @testing.fixture( + params=[ + ("ANY", lambda x, *o: x.any(*o)), + ("ALL", lambda x, *o: x.all(*o)), + ] + ) + def legacy_any_all_operators(self, request): + return request.param + + def _array_any_deprecation(self): + return testing.expect_deprecated( + r"The ARRAY.Comparator.any\(\) and " + r"ARRAY.Comparator.all\(\) methods " + r"for arrays are deprecated for removal, along with the " + r"PG-specific Any\(\) " + r"and All\(\) functions. See any_\(\) and all_\(\) functions for " + "modern use. " + ) + + @testing.variation("operator", ["any", "all"]) + @testing.variation("datatype", ["array", "arraystring", "arrayenum"]) + def test_what_type_is_legacy_any_all( + self, + datatype: testing.Variation, + t_fixture, + operator: testing.Variation, + ): + if datatype.array: + col = t_fixture.c.arrval + value = 25 + expected_type_affinity = Integer + elif datatype.arraystring: + col = t_fixture.c.arrstring + value = "a string" + expected_type_affinity = String + elif datatype.arrayenum: + col = t_fixture.c.arrenum + value = MyEnum.TWO + expected_type_affinity = Enum + else: + datatype.fail() + + with self._array_any_deprecation(): + if operator.any: + boolean_expr = col.any(value) + elif operator.all: + boolean_expr = col.all(value) + else: + operator.fail() + + # using isinstance so things work out for Enum which has type affinity + # of String + assert isinstance(boolean_expr.left.type, expected_type_affinity) + + def test_bindparam_coercion(self, t_fixture, legacy_any_all_operators): + """test #7979""" + t = t_fixture + op, fn = legacy_any_all_operators + + with self._array_any_deprecation(): + expr = fn(t.c.arrval, bindparam("param")) + expected = f"%(param)s = {op} (tab1.arrval)" + is_(expr.left.type._type_affinity, Integer) + + self.assert_compile(expr, expected, dialect="postgresql") + + def test_array_comparator_accessor( + self, t_fixture, legacy_any_all_operators + ): + t = t_fixture + op, fn = legacy_any_all_operators + + with self._array_any_deprecation(): + self.assert_compile( + fn(t.c.arrval, 5, operator.gt), + f":arrval_1 > {op} (tab1.arrval)", + checkparams={"arrval_1": 5}, + ) + + def test_array_comparator_negate_accessor( + self, t_fixture, legacy_any_all_operators + ): + t = t_fixture + op, fn = legacy_any_all_operators + + with self._array_any_deprecation(): + self.assert_compile( + ~fn(t.c.arrval, 5, operator.gt), + f"NOT (:arrval_1 > {op} (tab1.arrval))", + checkparams={"arrval_1": 5}, + ) + + class BitOpTest(fixtures.TestBase, testing.AssertsCompiledSQL): __dialect__ = "default" diff --git a/test/sql/test_types.py b/test/sql/test_types.py index 9d3e0ae38c..9e4ac9823f 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -1030,8 +1030,8 @@ class TypeDecoratorSpecialCasesTest(AssertsCompiledSQL, fixtures.TestBase): eq_(expr2.right.type._type_affinity, Integer) self.assert_compile( - column("q", ArrayDec).any(7, operator=operators.lt), - "%(q_1)s < ANY (q)", + 7 < column("q", ArrayDec).any_(), + "%(param_1)s < ANY (q)", dialect="postgresql", )