From dad9656047d885c7581f7a12183c3a28d88933c4 Mon Sep 17 00:00:00 2001 From: henadzit Date: Fri, 22 Nov 2024 18:48:34 +0100 Subject: [PATCH 1/4] Allow Array parametrization --- pypika/terms.py | 24 +++++++++++++++++------- tests/test_tuples.py | 9 ++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/pypika/terms.py b/pypika/terms.py index f6b12df..f383389 100644 --- a/pypika/terms.py +++ b/pypika/terms.py @@ -776,15 +776,25 @@ def replace_table( # type:ignore[return] class Array(Tuple): - def get_sql(self, **kwargs: Any) -> str: - dialect = kwargs.get("dialect", None) - values = ",".join(term.get_sql(**kwargs) for term in self.values) # type:ignore[union-attr] + def __init__(self, *values: Any) -> None: + super().__init__(*values) + self.original_value = list(values) - sql = "[{}]".format(values) - if dialect in (Dialects.POSTGRESQL, Dialects.REDSHIFT): - sql = "ARRAY[{}]".format(values) if len(values) > 0 else "'{}'" + def get_sql(self, parameterizer: Parameterizer | None = None, **kwargs: Any) -> str: + if parameterizer is None or not parameterizer.should_parameterize(self.original_value): + dialect = kwargs.get("dialect", None) + values = ",".join( + term.get_sql(**kwargs) for term in self.values + ) # type:ignore[union-attr] - return format_alias_sql(sql, self.alias, **kwargs) + sql = "[{}]".format(values) + if dialect in (Dialects.POSTGRESQL, Dialects.REDSHIFT): + sql = "ARRAY[{}]".format(values) if len(values) > 0 else "'{}'" + + return format_alias_sql(sql, self.alias, **kwargs) + + param = parameterizer.create_param(self.original_value) + return param.get_sql(**kwargs) class Bracket(Tuple): diff --git a/tests/test_tuples.py b/tests/test_tuples.py index 35c956a..fa0dc98 100644 --- a/tests/test_tuples.py +++ b/tests/test_tuples.py @@ -2,7 +2,7 @@ from pypika import Array, Bracket, PostgreSQLQuery, Query, Table, Tables, Tuple from pypika.functions import Coalesce, NullIf, Sum -from pypika.terms import Field +from pypika.terms import Field, Parameterizer, Star class TupleTests(unittest.TestCase): @@ -149,6 +149,13 @@ def test_render_alias_in_array_sql(self): q = Query.from_(tb).select(Array(tb.col).as_("different_name")) self.assertEqual(str(q), 'SELECT ["col"] "different_name" FROM "tb"') + def test_parametrization(self): + q = Query.from_(self.table_abc).select(Star()).where(self.table_abc.f == Array(1, 2, 3)) + + parameterizer = Parameterizer() + sql = q.get_sql(parameterizer=parameterizer) + self.assertEqual('SELECT * FROM "abc" WHERE "f"=?', sql) + class BracketTests(unittest.TestCase): table_abc, table_efg = Tables("abc", "efg") From 3574e452523988b26d8cee5c802929d54c28e475 Mon Sep 17 00:00:00 2001 From: henadzit Date: Sat, 23 Nov 2024 13:20:57 +0100 Subject: [PATCH 2/4] Do not call wrap_constant twice in isin filter --- pypika/terms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypika/terms.py b/pypika/terms.py index f383389..eeb7917 100644 --- a/pypika/terms.py +++ b/pypika/terms.py @@ -210,7 +210,7 @@ def all_(self) -> "All": def isin(self, arg: list | tuple | set | "Term") -> "ContainsCriterion": if isinstance(arg, (list, tuple, set)): - return ContainsCriterion(self, Tuple(*[self.wrap_constant(value) for value in arg])) + return ContainsCriterion(self, Tuple(*arg)) return ContainsCriterion(self, arg) def notin(self, arg: list | tuple | set | "Term") -> "ContainsCriterion": From 0a6a762d74937224212628f87dc47e9628dec404 Mon Sep 17 00:00:00 2001 From: henadzit Date: Sat, 23 Nov 2024 13:24:32 +0100 Subject: [PATCH 3/4] Release 0.3.1 --- CHANGELOG.md | 5 ++++- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4e1752..3699c49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## 0.3 -## 0.3.0 +### 0.3.1 +- `Array` can be parametrized + +### 0.3.0 - Add `Parameterizer` - Uppdate `Parameter` to be dialect-aware - Remove `ListParameter`, `DictParameter`, `QmarkParameter`, etc. diff --git a/pyproject.toml b/pyproject.toml index 8887e9a..3d428db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pypika-tortoise" -version = "0.3.0" +version = "0.3.1" description = "Forked from pypika and streamline just for tortoise-orm" authors = ["long2ice "] license = "Apache-2.0" From 59e9205afb5affee7872e012fd9a20e86a9524a7 Mon Sep 17 00:00:00 2001 From: henadzit Date: Sat, 23 Nov 2024 13:36:45 +0100 Subject: [PATCH 4/4] Fix typing issue --- pypika/terms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pypika/terms.py b/pypika/terms.py index eeb7917..c0679f1 100644 --- a/pypika/terms.py +++ b/pypika/terms.py @@ -69,7 +69,7 @@ def fields_(self) -> set["Field"]: @staticmethod def wrap_constant( val, wrapper_cls: Type["Term"] | None = None - ) -> ValueError | NodeT | "LiteralValue" | "Array" | "Tuple" | "ValueWrapper": + ) -> NodeT | "LiteralValue" | "Array" | "Tuple" | "ValueWrapper": """ Used for wrapping raw inputs such as numbers in Criterions and Operator.