diff --git a/pypika/dialects.py b/pypika/dialects.py index dab72e07..2255243b 100644 --- a/pypika/dialects.py +++ b/pypika/dialects.py @@ -796,9 +796,14 @@ class ClickHouseQueryBuilder(QueryBuilder): def __init__(self, **kwargs) -> None: super().__init__(**kwargs) + self._final = False self._sample = None self._sample_offset = None + @builder + def final(self) -> "ClickHouseQueryBuilder": + self._final = True + @builder def sample(self, sample: int, offset: Optional[int] = None) -> "ClickHouseQueryBuilder": self._sample = sample @@ -816,6 +821,8 @@ def _from_sql(self, with_namespace: bool = False, **kwargs: Any) -> str: if self._delete_from: return " {selectable} DELETE".format(selectable=selectable) clauses = [selectable] + if self._final is not False: + clauses.append("FINAL") if self._sample is not None: clauses.append(f"SAMPLE {self._sample}") if self._sample_offset is not None: diff --git a/pypika/tests/dialects/test_clickhouse.py b/pypika/tests/dialects/test_clickhouse.py index 8da62701..62afd7c2 100644 --- a/pypika/tests/dialects/test_clickhouse.py +++ b/pypika/tests/dialects/test_clickhouse.py @@ -23,6 +23,11 @@ def test_use_SAMPLE_with_offset_keyword(self): query = ClickHouseQuery.from_(t).select(t.foo).sample(10, 5) self.assertEqual(str(query), 'SELECT "foo" FROM "abc" SAMPLE 10 OFFSET 5') + def test_use_FINAL_keyword(self): + t = Table('abc') + query = ClickHouseQuery.from_(t).select(t.foo).final() + self.assertEqual(str(query), 'SELECT "foo" FROM "abc" FINAL') + class ClickHouseDeleteTests(TestCase): table_abc = Table("abc")