summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects/clickhouse.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-16 09:41:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-16 09:41:18 +0000
commit67578a7602a5be7eb51f324086c8d49bcf8b7498 (patch)
tree0b7515c922d1c383cea24af5175379cfc8edfd15 /sqlglot/dialects/clickhouse.py
parentReleasing debian version 15.2.0-1. (diff)
downloadsqlglot-67578a7602a5be7eb51f324086c8d49bcf8b7498.tar.xz
sqlglot-67578a7602a5be7eb51f324086c8d49bcf8b7498.zip
Merging upstream version 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.py38
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")