Skip to content

Commit 62c0ef0

Browse files
authored
fix(duckdb)!: Fix BQ's exp.Date transpilation (#6595)
1 parent 87fda9d commit 62c0ef0

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

sqlglot/dialects/duckdb.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,20 @@ def _to_boolean_sql(self: DuckDB.Generator, expression: exp.ToBoolean) -> str:
144144

145145
# BigQuery -> DuckDB conversion for the DATE function
146146
def _date_sql(self: DuckDB.Generator, expression: exp.Date) -> str:
147-
result = f"CAST({self.sql(expression, 'this')} AS DATE)"
147+
this = expression.this
148148
zone = self.sql(expression, "zone")
149149

150150
if zone:
151-
date_str = self.func("STRFTIME", result, "'%d/%m/%Y'")
152-
date_str = f"{date_str} || ' ' || {zone}"
153-
154-
# This will create a TIMESTAMP with time zone information
155-
result = self.func("STRPTIME", date_str, "'%d/%m/%Y %Z'")
156-
157-
return result
151+
# BigQuery considers "this" at UTC, converts it to the specified
152+
# time zone and then keeps only the DATE part
153+
# To micmic that, we:
154+
# (1) Cast to TIMESTAMP to remove DuckDB's local tz
155+
# (2) Apply consecutive AtTimeZone calls for UTC -> zone conversion
156+
this = exp.cast(this, exp.DataType.Type.TIMESTAMP)
157+
at_utc = exp.AtTimeZone(this=this, zone=exp.Literal.string("UTC"))
158+
this = exp.AtTimeZone(this=at_utc, zone=zone)
159+
160+
return self.sql(exp.cast(expression=this, to=exp.DataType.Type.DATE))
158161

159162

160163
# BigQuery -> DuckDB conversion for the TIME_DIFF function

tests/dialects/test_duckdb.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,11 +1358,17 @@ def test_time(self):
13581358
read={"bigquery": "SELECT DATE(DATETIME '2016-12-25 23:59:59')"},
13591359
)
13601360
self.validate_all(
1361-
"SELECT STRPTIME(STRFTIME(CAST(CAST('2016-12-25' AS TIMESTAMPTZ) AS DATE), '%d/%m/%Y') || ' ' || 'America/Los_Angeles', '%d/%m/%Y %Z')",
1361+
"SELECT CAST(CAST(CAST('2016-12-25' AS TIMESTAMPTZ) AS TIMESTAMP) AT TIME ZONE 'UTC' AT TIME ZONE 'America/Los_Angeles' AS DATE)",
13621362
read={
13631363
"bigquery": "SELECT DATE(TIMESTAMP '2016-12-25', 'America/Los_Angeles')",
13641364
},
13651365
)
1366+
self.validate_all(
1367+
"SELECT CAST(CAST('2024-01-15 23:30:00' AS TIMESTAMP) AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Berlin' AS DATE)",
1368+
read={
1369+
"bigquery": "SELECT DATE('2024-01-15 23:30:00', 'Europe/Berlin')",
1370+
},
1371+
)
13661372
self.validate_all(
13671373
"SELECT CAST(CAST(STRPTIME('05/06/2020', '%m/%d/%Y') AS DATE) AS DATE)",
13681374
read={"bigquery": "SELECT DATE(PARSE_DATE('%m/%d/%Y', '05/06/2020'))"},

0 commit comments

Comments
 (0)