diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-06-16 09:41:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-06-16 09:41:15 +0000 |
commit | 358a09296d7198a4cc142f1976de8f3eb3318e58 (patch) | |
tree | 762db96c44014dc4db5e9fc7f6709c138589155e /sqlglot/dialects/clickhouse.py | |
parent | Adding upstream version 15.2.0. (diff) | |
download | sqlglot-upstream/16.2.1.tar.xz sqlglot-upstream/16.2.1.zip |
Adding upstream version 16.2.1.upstream/16.2.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/dialects/clickhouse.py')
-rw-r--r-- | sqlglot/dialects/clickhouse.py | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py index fc48379..cfa9a7e 100644 --- a/sqlglot/dialects/clickhouse.py +++ b/sqlglot/dialects/clickhouse.py @@ -21,8 +21,9 @@ def _lower_func(sql: str) -> str: class ClickHouse(Dialect): - normalize_functions = None - null_ordering = "nulls_are_last" + NORMALIZE_FUNCTIONS: bool | str = False + NULL_ORDERING = "nulls_are_last" + STRICT_STRING_CONCAT = True class Tokenizer(tokens.Tokenizer): COMMENTS = ["--", "#", "#!", ("/*", "*/")] @@ -163,11 +164,11 @@ class ClickHouse(Dialect): return this - def _parse_position(self, haystack_first: bool = False) -> exp.Expression: + def _parse_position(self, haystack_first: bool = False) -> exp.StrPosition: return super()._parse_position(haystack_first=True) # https://clickhouse.com/docs/en/sql-reference/statements/select/with/ - def _parse_cte(self) -> exp.Expression: + def _parse_cte(self) -> exp.CTE: index = self._index try: # WITH <identifier> AS <subquery expression> @@ -187,17 +188,19 @@ class ClickHouse(Dialect): ) -> t.Tuple[t.Optional[Token], t.Optional[Token], t.Optional[Token]]: is_global = self._match(TokenType.GLOBAL) and self._prev kind_pre = self._match_set(self.JOIN_KINDS, advance=False) and self._prev + if kind_pre: kind = self._match_set(self.JOIN_KINDS) and self._prev side = self._match_set(self.JOIN_SIDES) and self._prev return is_global, side, kind + return ( is_global, self._match_set(self.JOIN_SIDES) and self._prev, self._match_set(self.JOIN_KINDS) and self._prev, ) - def _parse_join(self, skip_join_token: bool = False) -> t.Optional[exp.Expression]: + def _parse_join(self, skip_join_token: bool = False) -> t.Optional[exp.Join]: join = super()._parse_join(skip_join_token) if join: @@ -205,9 +208,14 @@ class ClickHouse(Dialect): return join def _parse_function( - self, functions: t.Optional[t.Dict[str, t.Callable]] = None, anonymous: bool = False + self, + functions: t.Optional[t.Dict[str, t.Callable]] = None, + anonymous: bool = False, + optional_parens: bool = True, ) -> t.Optional[exp.Expression]: - func = super()._parse_function(functions, anonymous) + func = super()._parse_function( + functions=functions, anonymous=anonymous, optional_parens=optional_parens + ) if isinstance(func, exp.Anonymous): params = self._parse_func_params(func) @@ -227,10 +235,12 @@ class ClickHouse(Dialect): ) -> t.Optional[t.List[t.Optional[exp.Expression]]]: if self._match_pair(TokenType.R_PAREN, TokenType.L_PAREN): return self._parse_csv(self._parse_lambda) + if self._match(TokenType.L_PAREN): params = self._parse_csv(self._parse_lambda) self._match_r_paren(this) return params + return None def _parse_quantile(self) -> exp.Quantile: @@ -247,12 +257,12 @@ class ClickHouse(Dialect): def _parse_primary_key( self, wrapped_optional: bool = False, in_props: bool = False - ) -> exp.Expression: + ) -> exp.PrimaryKeyColumnConstraint | exp.PrimaryKey: return super()._parse_primary_key( wrapped_optional=wrapped_optional or in_props, in_props=in_props ) - def _parse_on_property(self) -> t.Optional[exp.Property]: + def _parse_on_property(self) -> t.Optional[exp.Expression]: index = self._index if self._match_text_seq("CLUSTER"): this = self._parse_id_var() @@ -329,6 +339,16 @@ class ClickHouse(Dialect): "NAMED COLLECTION", } + def safeconcat_sql(self, expression: exp.SafeConcat) -> str: + # Clickhouse errors out if we try to cast a NULL value to TEXT + return self.func( + "CONCAT", + *[ + exp.func("if", e.is_(exp.null()), e, exp.cast(e, "text")) + for e in expression.expressions + ], + ) + def cte_sql(self, expression: exp.CTE) -> str: if isinstance(expression.this, exp.Alias): return self.sql(expression, "this") |