diff options
Diffstat (limited to 'sqlglot/dialects/clickhouse.py')
-rw-r--r-- | sqlglot/dialects/clickhouse.py | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py index cfde5fd..a38a239 100644 --- a/sqlglot/dialects/clickhouse.py +++ b/sqlglot/dialects/clickhouse.py @@ -11,6 +11,7 @@ from sqlglot.dialects.dialect import ( var_map_sql, ) from sqlglot.errors import ParseError +from sqlglot.helper import seq_get from sqlglot.parser import parse_var_map from sqlglot.tokens import Token, TokenType @@ -63,9 +64,23 @@ class ClickHouse(Dialect): } class Parser(parser.Parser): + SUPPORTS_USER_DEFINED_TYPES = False + FUNCTIONS = { **parser.Parser.FUNCTIONS, "ANY": exp.AnyValue.from_arg_list, + "DATE_ADD": lambda args: exp.DateAdd( + this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) + ), + "DATEADD": lambda args: exp.DateAdd( + this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) + ), + "DATE_DIFF": lambda args: exp.DateDiff( + this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) + ), + "DATEDIFF": lambda args: exp.DateDiff( + this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) + ), "MAP": parse_var_map, "MATCH": exp.RegexpLike.from_arg_list, "UNIQ": exp.ApproxDistinct.from_arg_list, @@ -147,7 +162,7 @@ class ClickHouse(Dialect): this = self._parse_id_var() self._match(TokenType.COLON) - kind = self._parse_types(check_func=False) or ( + kind = self._parse_types(check_func=False, allow_identifiers=False) or ( self._match_text_seq("IDENTIFIER") and "Identifier" ) @@ -249,7 +264,7 @@ class ClickHouse(Dialect): def _parse_func_params( self, this: t.Optional[exp.Func] = None - ) -> t.Optional[t.List[t.Optional[exp.Expression]]]: + ) -> t.Optional[t.List[exp.Expression]]: if self._match_pair(TokenType.R_PAREN, TokenType.L_PAREN): return self._parse_csv(self._parse_lambda) @@ -267,9 +282,7 @@ class ClickHouse(Dialect): return self.expression(exp.Quantile, this=params[0], quantile=this) return self.expression(exp.Quantile, this=this, quantile=exp.Literal.number(0.5)) - def _parse_wrapped_id_vars( - self, optional: bool = False - ) -> t.List[t.Optional[exp.Expression]]: + def _parse_wrapped_id_vars(self, optional: bool = False) -> t.List[exp.Expression]: return super()._parse_wrapped_id_vars(optional=True) def _parse_primary_key( @@ -292,9 +305,22 @@ class ClickHouse(Dialect): class Generator(generator.Generator): QUERY_HINTS = False STRUCT_DELIMITER = ("(", ")") + NVL2_SUPPORTED = False + + STRING_TYPE_MAPPING = { + exp.DataType.Type.CHAR: "String", + exp.DataType.Type.LONGBLOB: "String", + exp.DataType.Type.LONGTEXT: "String", + exp.DataType.Type.MEDIUMBLOB: "String", + exp.DataType.Type.MEDIUMTEXT: "String", + exp.DataType.Type.TEXT: "String", + exp.DataType.Type.VARBINARY: "String", + exp.DataType.Type.VARCHAR: "String", + } TYPE_MAPPING = { **generator.Generator.TYPE_MAPPING, + **STRING_TYPE_MAPPING, exp.DataType.Type.ARRAY: "Array", exp.DataType.Type.BIGINT: "Int64", exp.DataType.Type.DATETIME64: "DateTime64", @@ -328,6 +354,12 @@ class ClickHouse(Dialect): exp.ApproxDistinct: rename_func("uniq"), exp.Array: inline_array_sql, exp.CastToStrType: rename_func("CAST"), + exp.DateAdd: lambda self, e: self.func( + "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this + ), + exp.DateDiff: lambda self, e: self.func( + "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this + ), exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL", exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)), exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", @@ -364,6 +396,16 @@ class ClickHouse(Dialect): "NAMED COLLECTION", } + def datatype_sql(self, expression: exp.DataType) -> str: + # String is the standard ClickHouse type, every other variant is just an alias. + # Additionally, any supplied length parameter will be ignored. + # + # https://clickhouse.com/docs/en/sql-reference/data-types/string + if expression.this in self.STRING_TYPE_MAPPING: + return "String" + + return super().datatype_sql(expression) + def safeconcat_sql(self, expression: exp.SafeConcat) -> str: # Clickhouse errors out if we try to cast a NULL value to TEXT expression = expression.copy() |