Skip to content

Commit 7fb986b

Browse files
authored
SNOW-2397758: Add parameter for aliasing interval function names (#3859)
1 parent 5ce80df commit 7fb986b

File tree

3 files changed

+57
-15
lines changed

3 files changed

+57
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
- `st_geometryfromwkt`
5959
- `try_to_geography`
6060
- `try_to_geometry`
61-
61+
- Added a parameter to enable and disable automatic column name aliasing for `interval_day_time_from_parts` and `interval_year_month_from_parts` functions.
6262

6363
#### Bug Fixes
6464

src/snowflake/snowpark/functions.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11031,6 +11031,7 @@ def make_interval(
1103111031
def interval_year_month_from_parts(
1103211032
years: Optional[ColumnOrName] = None,
1103311033
months: Optional[ColumnOrName] = None,
11034+
_alias_column_name: Optional[bool] = True,
1103411035
_emit_ast: bool = True,
1103511036
) -> Column:
1103611037
"""
@@ -11042,6 +11043,7 @@ def interval_year_month_from_parts(
1104211043
Args:
1104311044
years: The number of years, positive or negative
1104411045
months: The number of months, positive or negative
11046+
_alias_column_name: If true, alias the column name to a cleaner value
1104511047

1104611048
Returns:
1104711049
A Column representing a year-month interval
@@ -11091,15 +11093,21 @@ def interval_year_month_from_parts(
1109111093
)
1109211094
interval_string = concat(sign_prefix, normalized_years, lit("-"), normalized_months)
1109311095

11094-
def get_col_name(col):
11095-
if isinstance(col._expr1, Literal):
11096-
return str(col._expr1.value)
11097-
else:
11098-
return col._expression.name
11096+
res = cast(interval_string, "INTERVAL YEAR TO MONTH")
11097+
if _alias_column_name:
11098+
# Aliasing column names when using this in a case when will throw an error. This allows us to only alias
11099+
# when necessary.
11100+
11101+
def get_col_name(col):
11102+
if isinstance(col._expr1, Literal):
11103+
return str(col._expr1.value)
11104+
else:
11105+
return col._expression.name
11106+
11107+
alias_name = f"interval_year_month_from_parts({get_col_name(years_col)}, {get_col_name(months_col)})"
1109911108

11100-
alias_name = f"interval_year_month_from_parts({get_col_name(years_col)}, {get_col_name(months_col)})"
11109+
res = res.alias(alias_name)
1110111110

11102-
res = cast(interval_string, "INTERVAL YEAR TO MONTH").alias(alias_name)
1110311111
res._ast = ast
1110411112
return res
1110511113

@@ -11114,6 +11122,7 @@ def interval_day_time_from_parts(
1111411122
hours: Optional[ColumnOrName] = None,
1111511123
mins: Optional[ColumnOrName] = None,
1111611124
secs: Optional[ColumnOrName] = None,
11125+
_alias_column_name: Optional[bool] = True,
1111711126
_emit_ast: bool = True,
1111811127
) -> Column:
1111911128
"""
@@ -11127,6 +11136,7 @@ def interval_day_time_from_parts(
1112711136
hours: The number of hours, positive or negative
1112811137
mins: The number of minutes, positive or negative
1112911138
secs: The number of seconds, positive or negative
11139+
_alias_column_name: If true, alias the column name to a cleaner value
1113011140

1113111141
Returns:
1113211142
A Column representing a day-time interval
@@ -11238,15 +11248,21 @@ def interval_day_time_from_parts(
1123811248
secs_formatted,
1123911249
)
1124011250

11241-
def get_col_name(col):
11242-
if isinstance(col._expr1, Literal):
11243-
return str(col._expr1.value)
11244-
else:
11245-
return str(col._expr1)
11251+
res = cast(interval_value, "INTERVAL DAY TO SECOND")
11252+
if _alias_column_name:
11253+
# Aliasing column names when using this in a case when will throw an error. This allows us to only alias
11254+
# when necessary.
11255+
11256+
def get_col_name(col):
11257+
if isinstance(col._expr1, Literal):
11258+
return str(col._expr1.value)
11259+
else:
11260+
return str(col._expr1)
11261+
11262+
alias_name = f"interval_day_time_from_parts({get_col_name(days_col)}, {get_col_name(hours_col)}, {get_col_name(mins_col)}, {get_col_name(secs_col)})"
1124611263

11247-
alias_name = f"interval_day_time_from_parts({get_col_name(days_col)}, {get_col_name(hours_col)}, {get_col_name(mins_col)}, {get_col_name(secs_col)})"
11264+
res = res.alias(alias_name)
1124811265

11249-
res = cast(interval_value, "INTERVAL DAY TO SECOND").alias(alias_name)
1125011266
res._ast = ast
1125111267
return res
1125211268

tests/integ/scala/test_function_suite.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5727,6 +5727,21 @@ def test_interval_year_month_from_parts(session):
57275727
assert result_nulls[1]['interval_year_month_from_parts("YEARS", "MONTHS")'] is None
57285728
assert result_nulls[2]['interval_year_month_from_parts("YEARS", "MONTHS")'] is None
57295729

5730+
df_literals = session.create_dataframe([(1,)], schema=["dummy"])
5731+
literals_schema_result_no_alias = df_literals.select(
5732+
interval_year_month_from_parts(lit(2), lit(5), _alias_column_name=False),
5733+
)
5734+
for field in literals_schema_result_no_alias.schema.fields:
5735+
assert field.datatype == YearMonthIntervalType(0, 1)
5736+
5737+
result_literals_no_alias = literals_schema_result_no_alias.collect()
5738+
assert (
5739+
result_literals_no_alias[0][
5740+
"CAST (CONCAT(IFF((((2 * 12) + 5) < 0), '-', ''), CAST ( CAST (FLOOR((ABS(((2 * 12) + 5)) / 12)) AS INT) AS STRING), '-', CAST ( CAST (FLOOR((ABS(((2 * 12) + 5)) % 12)) AS INT) AS STRING)) AS INTERVAL YEAR TO MONTH)"
5741+
]
5742+
== "+2-05"
5743+
)
5744+
57305745

57315746
@pytest.mark.skipif(
57325747
"config.getoption('local_testing_mode', default=False)",
@@ -5944,3 +5959,14 @@ def test_interval_day_time_from_parts(session):
59445959
interval_result = result_microsecond[0]["MICROSECOND_TEST"]
59455960
expected = timedelta(seconds=0.123456)
59465961
assert interval_result == expected
5962+
5963+
df_literals = session.create_dataframe([(1,)], schema=["dummy"])
5964+
literals_schema_result_no_alias = df_literals.select(
5965+
interval_day_time_from_parts(
5966+
lit(1), lit(2), lit(3), lit(4.5), _alias_column_name=False
5967+
),
5968+
)
5969+
literals_result_no_alias = literals_schema_result_no_alias.collect()
5970+
assert literals_result_no_alias[0][
5971+
"CAST (CONCAT(IFF((((((1 * 86400) + (2 * 3600)) + (3 * 60)) + 4.5) < 0), '-', ''), CAST ( CAST (FLOOR((ABS(((((1 * 86400) + (2 * 3600)) + (3 * 60)) + 4.5)) / 86400)) AS INT) AS STRING), ' ', IFF(( CAST (FLOOR(((ABS(((((1 * 86400) + (2 * 3600)) + (3 * 60))"
5972+
] == timedelta(days=1, hours=2, minutes=3, seconds=4.5)

0 commit comments

Comments
 (0)