Skip to content

Commit dfb72b6

Browse files
authored
SNOW-2392212: Fix floating point precision bug in interval_day_time_f… (#3847)
1 parent 2f09d5e commit dfb72b6

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#### Bug Fixes
3535

36+
- Added a fix for floating point precision discrepancies in `interval_day_time_from_parts`.
3637
- Fixed a bug where writing Snowpark pandas dataframes on the pandas backend with a column multiindex to Snowflake with `to_snowflake` would raise `KeyError`.
3738
- Fixed a bug that `DataFrameReader.dbapi` (PuPr) is not compatible with oracledb 3.4.0.
3839

src/snowflake/snowpark/functions.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11141,7 +11141,7 @@ def interval_day_time_from_parts(
1114111141
--------------------------
1114211142
|"INTERVAL" |
1114311143
--------------------------
11144-
|1 day, 12:30:01.001000 |
11144+
|1 day, 12:30:01.001001 |
1114511145
--------------------------
1114611146
<BLANKLINE>
1114711147

@@ -11208,16 +11208,16 @@ def interval_day_time_from_parts(
1120811208
cast(secs_int, "str"),
1120911209
)
1121011210

11211-
has_fraction = abs(secs_part - cast(secs_int, "double")) > 1e-10
11212-
fractional_part = secs_part - cast(secs_int, "double")
11211+
has_fraction = abs(secs_part - cast(secs_int, "decimal")) > 1e-15
11212+
fractional_part = secs_part - cast(secs_int, "decimal")
1121311213

1121411214
fraction_str = iff(
1121511215
has_fraction,
1121611216
concat(
1121711217
lit("."),
1121811218
lpad(
11219-
cast(round(fractional_part * lit(1000), 0), "str"),
11220-
3,
11219+
cast(round(fractional_part * lit(1000000), 0), "str"),
11220+
6,
1122111221
lit("0"),
1122211222
),
1122311223
),

tests/integ/scala/test_function_suite.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5917,3 +5917,30 @@ def test_interval_day_time_from_parts(session):
59175917
assert result_nulls[2]["INTERVAL_RESULT"] is None
59185918
assert result_nulls[3]["INTERVAL_RESULT"] is None
59195919
assert result_nulls[4]["INTERVAL_RESULT"] is None
5920+
5921+
df_extreme = session.create_dataframe(
5922+
[[1, 0, 0, 123456789012.123456]], ["days", "hours", "mins", "secs"]
5923+
)
5924+
result_extreme = df_extreme.select(
5925+
interval_day_time_from_parts(
5926+
col("days"), col("hours"), col("mins"), col("secs")
5927+
).alias("extreme_interval")
5928+
).collect()
5929+
5930+
interval_result = result_extreme[0]["EXTREME_INTERVAL"]
5931+
assert isinstance(interval_result, timedelta)
5932+
total_seconds = interval_result.total_seconds()
5933+
expected_total = 86400 + 123456789012.123456
5934+
import builtins
5935+
5936+
assert builtins.abs(total_seconds - expected_total) < 1e-6
5937+
5938+
result_microsecond = df_extreme.select(
5939+
interval_day_time_from_parts(lit(0), lit(0), lit(0), lit(0.123456)).alias(
5940+
"microsecond_test"
5941+
)
5942+
).collect()
5943+
5944+
interval_result = result_microsecond[0]["MICROSECOND_TEST"]
5945+
expected = timedelta(seconds=0.123456)
5946+
assert interval_result == expected

0 commit comments

Comments
 (0)