Adding upstream version 25.7.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
f9dae8e951
commit
8356f462bb
102 changed files with 52995 additions and 52070 deletions
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import typing as t
|
||||
|
||||
from sqlglot import exp, generator, parser, tokens, transforms
|
||||
from sqlglot.expressions import DATA_TYPE
|
||||
from sqlglot.dialects.dialect import (
|
||||
Dialect,
|
||||
JSON_EXTRACT_TYPE,
|
||||
|
@ -35,20 +36,34 @@ from sqlglot.dialects.dialect import (
|
|||
from sqlglot.helper import seq_get
|
||||
from sqlglot.tokens import TokenType
|
||||
|
||||
|
||||
def _ts_or_ds_add_sql(self: DuckDB.Generator, expression: exp.TsOrDsAdd) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
interval = self.sql(exp.Interval(this=expression.expression, unit=unit_to_var(expression)))
|
||||
return f"CAST({this} AS {self.sql(expression.return_type)}) + {interval}"
|
||||
DATETIME_DELTA = t.Union[
|
||||
exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd, exp.DateSub, exp.DatetimeSub
|
||||
]
|
||||
|
||||
|
||||
def _date_delta_sql(
|
||||
self: DuckDB.Generator, expression: exp.DateAdd | exp.DateSub | exp.TimeAdd
|
||||
) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
def _date_delta_sql(self: DuckDB.Generator, expression: DATETIME_DELTA) -> str:
|
||||
this = expression.this
|
||||
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))}"
|
||||
op = (
|
||||
"+"
|
||||
if isinstance(expression, (exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd))
|
||||
else "-"
|
||||
)
|
||||
|
||||
to_type: t.Optional[DATA_TYPE] = None
|
||||
if isinstance(expression, exp.TsOrDsAdd):
|
||||
to_type = expression.return_type
|
||||
elif this.is_string:
|
||||
# Cast string literals (i.e function parameters) to the appropriate type for +/- interval to work
|
||||
to_type = (
|
||||
exp.DataType.Type.DATETIME
|
||||
if isinstance(expression, (exp.DatetimeAdd, exp.DatetimeSub))
|
||||
else exp.DataType.Type.DATE
|
||||
)
|
||||
|
||||
this = exp.cast(this, to_type) if to_type else this
|
||||
|
||||
return f"{self.sql(this)} {op} {self.sql(exp.Interval(this=expression.expression, unit=unit))}"
|
||||
|
||||
|
||||
# BigQuery -> DuckDB conversion for the DATE function
|
||||
|
@ -119,7 +134,12 @@ def _struct_sql(self: DuckDB.Generator, expression: exp.Struct) -> str:
|
|||
|
||||
# BigQuery allows inline construction such as "STRUCT<a STRING, b INTEGER>('str', 1)" which is
|
||||
# canonicalized to "ROW('str', 1) AS STRUCT(a TEXT, b INT)" in DuckDB
|
||||
is_struct_cast = expression.find_ancestor(exp.Cast)
|
||||
# The transformation to ROW will take place if a cast to STRUCT / ARRAY of STRUCTs is found
|
||||
ancestor_cast = expression.find_ancestor(exp.Cast)
|
||||
is_struct_cast = ancestor_cast and any(
|
||||
casted_type.is_type(exp.DataType.Type.STRUCT)
|
||||
for casted_type in ancestor_cast.find_all(exp.DataType)
|
||||
)
|
||||
|
||||
for i, expr in enumerate(expression.expressions):
|
||||
is_property_eq = isinstance(expr, exp.PropertyEQ)
|
||||
|
@ -168,7 +188,7 @@ def _unix_to_time_sql(self: DuckDB.Generator, expression: exp.UnixToTime) -> str
|
|||
|
||||
def _arrow_json_extract_sql(self: DuckDB.Generator, expression: JSON_EXTRACT_TYPE) -> str:
|
||||
arrow_sql = arrow_json_extract_sql(self, expression)
|
||||
if not expression.same_parent and isinstance(expression.parent, exp.Binary):
|
||||
if not expression.same_parent and isinstance(expression.parent, (exp.Binary, exp.Bracket)):
|
||||
arrow_sql = self.wrap(arrow_sql)
|
||||
return arrow_sql
|
||||
|
||||
|
@ -420,6 +440,8 @@ class DuckDB(Dialect):
|
|||
),
|
||||
exp.DateStrToDate: datestrtodate_sql,
|
||||
exp.Datetime: no_datetime_sql,
|
||||
exp.DatetimeSub: _date_delta_sql,
|
||||
exp.DatetimeAdd: _date_delta_sql,
|
||||
exp.DateToDi: lambda self,
|
||||
e: f"CAST(STRFTIME({self.sql(e, 'this')}, {DuckDB.DATEINT_FORMAT}) AS INT)",
|
||||
exp.Decode: lambda self, e: encode_decode_sql(self, e, "DECODE", replace=False),
|
||||
|
@ -484,7 +506,7 @@ class DuckDB(Dialect):
|
|||
exp.TimeToUnix: rename_func("EPOCH"),
|
||||
exp.TsOrDiToDi: lambda self,
|
||||
e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS TEXT), '-', ''), 1, 8) AS INT)",
|
||||
exp.TsOrDsAdd: _ts_or_ds_add_sql,
|
||||
exp.TsOrDsAdd: _date_delta_sql,
|
||||
exp.TsOrDsDiff: lambda self, e: self.func(
|
||||
"DATE_DIFF",
|
||||
f"'{e.args.get('unit') or 'DAY'}'",
|
||||
|
@ -790,3 +812,18 @@ class DuckDB(Dialect):
|
|||
)
|
||||
|
||||
return self.sql(case)
|
||||
|
||||
def objectinsert_sql(self, expression: exp.ObjectInsert) -> str:
|
||||
this = expression.this
|
||||
key = expression.args.get("key")
|
||||
key_sql = key.name if isinstance(key, exp.Expression) else ""
|
||||
value_sql = self.sql(expression, "value")
|
||||
|
||||
kv_sql = f"{key_sql} := {value_sql}"
|
||||
|
||||
# If the input struct is empty e.g. transpiling OBJECT_INSERT(OBJECT_CONSTRUCT(), key, value) from Snowflake
|
||||
# then we can generate STRUCT_PACK which will build it since STRUCT_INSERT({}, key := value) is not valid DuckDB
|
||||
if isinstance(this, exp.Struct) and not this.expressions:
|
||||
return self.func("STRUCT_PACK", kv_sql)
|
||||
|
||||
return self.func("STRUCT_INSERT", this, kv_sql)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue