diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 08:11:53 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 08:12:02 +0000 |
commit | 8d36f5966675e23bee7026ba37ae0647fbf47300 (patch) | |
tree | df4227bbb3b07cb70df87237bcff03c8efd7822d /sqlglot/dialects/duckdb.py | |
parent | Releasing debian version 22.2.0-1. (diff) | |
download | sqlglot-8d36f5966675e23bee7026ba37ae0647fbf47300.tar.xz sqlglot-8d36f5966675e23bee7026ba37ae0647fbf47300.zip |
Merging upstream version 23.7.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/dialects/duckdb.py')
-rw-r--r-- | sqlglot/dialects/duckdb.py | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py index f74dc97..6a1d07a 100644 --- a/sqlglot/dialects/duckdb.py +++ b/sqlglot/dialects/duckdb.py @@ -26,6 +26,7 @@ from sqlglot.dialects.dialect import ( str_to_time_sql, timestamptrunc_sql, timestrtotime_sql, + unit_to_var, ) from sqlglot.helper import flatten, seq_get from sqlglot.tokens import TokenType @@ -33,15 +34,16 @@ from sqlglot.tokens import TokenType def _ts_or_ds_add_sql(self: DuckDB.Generator, expression: exp.TsOrDsAdd) -> str: this = self.sql(expression, "this") - unit = self.sql(expression, "unit").strip("'") or "DAY" - interval = self.sql(exp.Interval(this=expression.expression, unit=unit)) + interval = self.sql(exp.Interval(this=expression.expression, unit=unit_to_var(expression))) return f"CAST({this} AS {self.sql(expression.return_type)}) + {interval}" -def _date_delta_sql(self: DuckDB.Generator, expression: exp.DateAdd | exp.DateSub) -> str: +def _date_delta_sql( + self: DuckDB.Generator, expression: exp.DateAdd | exp.DateSub | exp.TimeAdd +) -> str: this = self.sql(expression, "this") - unit = self.sql(expression, "unit").strip("'") or "DAY" - op = "+" if isinstance(expression, exp.DateAdd) else "-" + unit = unit_to_var(expression) + op = "+" if isinstance(expression, (exp.DateAdd, exp.TimeAdd)) else "-" return f"{this} {op} {self.sql(exp.Interval(this=expression.expression, unit=unit))}" @@ -186,6 +188,11 @@ class DuckDB(Dialect): return super().to_json_path(path) class Tokenizer(tokens.Tokenizer): + HEREDOC_STRINGS = ["$"] + + HEREDOC_TAG_IS_IDENTIFIER = True + HEREDOC_STRING_ALTERNATIVE = TokenType.PARAMETER + KEYWORDS = { **tokens.Tokenizer.KEYWORDS, "//": TokenType.DIV, @@ -199,6 +206,7 @@ class DuckDB(Dialect): "LOGICAL": TokenType.BOOLEAN, "ONLY": TokenType.ONLY, "PIVOT_WIDER": TokenType.PIVOT, + "POSITIONAL": TokenType.POSITIONAL, "SIGNED": TokenType.INT, "STRING": TokenType.VARCHAR, "UBIGINT": TokenType.UBIGINT, @@ -227,8 +235,8 @@ class DuckDB(Dialect): FUNCTIONS = { **parser.Parser.FUNCTIONS, "ARRAY_HAS": exp.ArrayContains.from_arg_list, - "ARRAY_SORT": exp.SortArray.from_arg_list, "ARRAY_REVERSE_SORT": _build_sort_array_desc, + "ARRAY_SORT": exp.SortArray.from_arg_list, "DATEDIFF": _build_date_diff, "DATE_DIFF": _build_date_diff, "DATE_TRUNC": date_trunc_to_time, @@ -285,6 +293,11 @@ class DuckDB(Dialect): FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy() FUNCTION_PARSERS.pop("DECODE") + NO_PAREN_FUNCTION_PARSERS = { + **parser.Parser.NO_PAREN_FUNCTION_PARSERS, + "MAP": lambda self: self._parse_map(), + } + TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS - { TokenType.SEMI, TokenType.ANTI, @@ -299,6 +312,13 @@ class DuckDB(Dialect): ), } + def _parse_map(self) -> exp.ToMap | exp.Map: + if self._match(TokenType.L_BRACE, advance=False): + return self.expression(exp.ToMap, this=self._parse_bracket()) + + args = self._parse_wrapped_csv(self._parse_conjunction) + return self.expression(exp.Map, keys=seq_get(args, 0), values=seq_get(args, 1)) + def _parse_types( self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True ) -> t.Optional[exp.Expression]: @@ -345,6 +365,7 @@ class DuckDB(Dialect): SUPPORTS_CREATE_TABLE_LIKE = False MULTI_ARG_DISTINCT = False CAN_IMPLEMENT_ARRAY_ANY = True + SUPPORTS_TO_NUMBER = False TRANSFORMS = { **generator.Generator.TRANSFORMS, @@ -425,6 +446,7 @@ class DuckDB(Dialect): "EPOCH", self.func("STRPTIME", e.this, self.format_time(e)) ), exp.Struct: _struct_sql, + exp.TimeAdd: _date_delta_sql, exp.Timestamp: no_timestamp_sql, exp.TimestampDiff: lambda self, e: self.func( "DATE_DIFF", exp.Literal.string(e.unit), e.expression, e.this @@ -478,7 +500,7 @@ class DuckDB(Dialect): STAR_MAPPING = {**generator.Generator.STAR_MAPPING, "except": "EXCLUDE"} - UNWRAPPED_INTERVAL_VALUES = (exp.Column, exp.Literal, exp.Paren) + UNWRAPPED_INTERVAL_VALUES = (exp.Literal, exp.Paren) # DuckDB doesn't generally support CREATE TABLE .. properties # https://duckdb.org/docs/sql/statements/create_table.html @@ -569,3 +591,9 @@ class DuckDB(Dialect): return rename_func("RANGE")(self, expression) return super().generateseries_sql(expression) + + def bracket_sql(self, expression: exp.Bracket) -> str: + if isinstance(expression.this, exp.Array): + expression.this.replace(exp.paren(expression.this)) + + return super().bracket_sql(expression) |