1818 bool_xor_sql ,
1919 build_default_decimal_type ,
2020 count_if_to_sum ,
21- date_delta_to_binary_interval_op as base_date_delta_to_binary_interval_op ,
21+ date_delta_to_binary_interval_op ,
2222 date_trunc_to_time ,
2323 datestrtodate_sql ,
2424 no_datetime_sql ,
@@ -162,23 +162,6 @@ def _handle_nanosecond_diff(
162162 )
163163
164164
165- def _handle_nanosecond_add (
166- self : DuckDB .Generator ,
167- timestamp : exp .Expression ,
168- nanoseconds : exp .Expression ,
169- ) -> str :
170- """Generate NANOSECOND add using EPOCH_NS and make_timestamp_ns since INTERVAL doesn't support it."""
171- timestamp_ns = exp .cast (timestamp , exp .DataType .Type .TIMESTAMP_NS )
172-
173- # Build expression tree: make_timestamp_ns(EPOCH_NS(timestamp) + nanoseconds)
174- return self .sql (
175- exp .func (
176- "make_timestamp_ns" ,
177- exp .Add (this = exp .func ("EPOCH_NS" , timestamp_ns ), expression = nanoseconds ),
178- )
179- )
180-
181-
182165def _to_boolean_sql (self : DuckDB .Generator , expression : exp .ToBoolean ) -> str :
183166 """
184167 Transpile TO_BOOLEAN and TRY_TO_BOOLEAN functions from Snowflake to DuckDB equivalent.
@@ -265,25 +248,33 @@ def _timediff_sql(self: DuckDB.Generator, expression: exp.TimeDiff) -> str:
265248 return self .func ("DATE_DIFF" , unit_to_str (expression ), expr , this )
266249
267250
268- def date_delta_to_binary_interval_op (
251+ def _date_delta_to_binary_interval_op (
269252 cast : bool = True ,
270253) -> t .Callable [[DuckDB .Generator , DATETIME_DELTA ], str ]:
271254 """DuckDB override to handle NANOSECOND operations; delegates other units to base."""
272- base_impl = base_date_delta_to_binary_interval_op (cast = cast )
255+ base_impl = date_delta_to_binary_interval_op (cast = cast )
273256
274- def duckdb_date_delta_sql (self : DuckDB .Generator , expression : DATETIME_DELTA ) -> str :
257+ def _duckdb_date_delta_sql (self : DuckDB .Generator , expression : DATETIME_DELTA ) -> str :
275258 unit = expression .unit
276259
277260 # Handle NANOSECOND unit (DuckDB doesn't support INTERVAL ... NANOSECOND)
278261 if _is_nanosecond_unit (unit ):
279262 interval_value = expression .expression
280263 if isinstance (interval_value , exp .Interval ):
281264 interval_value = interval_value .this
282- return _handle_nanosecond_add (self , expression .this , interval_value )
265+
266+ timestamp_ns = exp .cast (expression .this , exp .DataType .Type .TIMESTAMP_NS )
267+
268+ return self .sql (
269+ exp .func (
270+ "MAKE_TIMESTAMP_NS" ,
271+ exp .Add (this = exp .func ("EPOCH_NS" , timestamp_ns ), expression = interval_value ),
272+ )
273+ )
283274
284275 return base_impl (self , expression )
285276
286- return duckdb_date_delta_sql
277+ return _duckdb_date_delta_sql
287278
288279
289280@unsupported_args (("expression" , "DuckDB's ARRAY_SORT does not support a comparator." ))
@@ -1320,15 +1311,15 @@ class Generator(generator.Generator):
13201311 ),
13211312 exp .DataType : _datatype_sql ,
13221313 exp .Date : _date_sql ,
1323- exp .DateAdd : date_delta_to_binary_interval_op (),
1314+ exp .DateAdd : _date_delta_to_binary_interval_op (),
13241315 exp .DateFromParts : rename_func ("MAKE_DATE" ),
1325- exp .DateSub : date_delta_to_binary_interval_op (),
1316+ exp .DateSub : _date_delta_to_binary_interval_op (),
13261317 exp .DateDiff : _date_diff_sql ,
13271318 exp .DateStrToDate : datestrtodate_sql ,
13281319 exp .Datetime : no_datetime_sql ,
13291320 exp .DatetimeDiff : _date_diff_sql ,
1330- exp .DatetimeSub : date_delta_to_binary_interval_op (),
1331- exp .DatetimeAdd : date_delta_to_binary_interval_op (),
1321+ exp .DatetimeSub : _date_delta_to_binary_interval_op (),
1322+ exp .DatetimeAdd : _date_delta_to_binary_interval_op (),
13321323 exp .DateToDi : lambda self ,
13331324 e : f"CAST(STRFTIME({ self .sql (e , 'this' )} , { DuckDB .DATEINT_FORMAT } ) AS INT)" ,
13341325 exp .Decode : lambda self , e : encode_decode_sql (self , e , "DECODE" , replace = False ),
@@ -1392,16 +1383,16 @@ class Generator(generator.Generator):
13921383 ),
13931384 exp .Struct : _struct_sql ,
13941385 exp .Transform : rename_func ("LIST_TRANSFORM" ),
1395- exp .TimeAdd : date_delta_to_binary_interval_op (),
1396- exp .TimeSub : date_delta_to_binary_interval_op (),
1386+ exp .TimeAdd : _date_delta_to_binary_interval_op (),
1387+ exp .TimeSub : _date_delta_to_binary_interval_op (),
13971388 exp .Time : no_time_sql ,
13981389 exp .TimeDiff : _timediff_sql ,
13991390 exp .Timestamp : no_timestamp_sql ,
1400- exp .TimestampAdd : date_delta_to_binary_interval_op (),
1391+ exp .TimestampAdd : _date_delta_to_binary_interval_op (),
14011392 exp .TimestampDiff : lambda self , e : self .func (
14021393 "DATE_DIFF" , exp .Literal .string (e .unit ), e .expression , e .this
14031394 ),
1404- exp .TimestampSub : date_delta_to_binary_interval_op (),
1395+ exp .TimestampSub : _date_delta_to_binary_interval_op (),
14051396 exp .TimeStrToDate : lambda self , e : self .sql (exp .cast (e .this , exp .DataType .Type .DATE )),
14061397 exp .TimeStrToTime : timestrtotime_sql ,
14071398 exp .TimeStrToUnix : lambda self , e : self .func (
@@ -1412,7 +1403,7 @@ class Generator(generator.Generator):
14121403 exp .TimeToUnix : rename_func ("EPOCH" ),
14131404 exp .TsOrDiToDi : lambda self ,
14141405 e : f"CAST(SUBSTR(REPLACE(CAST({ self .sql (e , 'this' )} AS TEXT), '-', ''), 1, 8) AS INT)" ,
1415- exp .TsOrDsAdd : date_delta_to_binary_interval_op (),
1406+ exp .TsOrDsAdd : _date_delta_to_binary_interval_op (),
14161407 exp .TsOrDsDiff : lambda self , e : self .func (
14171408 "DATE_DIFF" ,
14181409 f"'{ e .args .get ('unit' ) or 'DAY' } '" ,
0 commit comments