This is an automated email from the ASF dual-hosted git repository.
maxgekk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 9858ab6d9c8e [SPARK-50055][SQL] Add TryMakeInterval alternative
9858ab6d9c8e is described below
commit 9858ab6d9c8e6f7c5fde4c6bbe96ca619cf7bdc8
Author: Mihailo Milosevic <[email protected]>
AuthorDate: Thu Nov 7 09:47:53 2024 +0100
[SPARK-50055][SQL] Add TryMakeInterval alternative
### What changes were proposed in this pull request?
Addition of two new expression try_make_interval.
### Why are the changes needed?
This is a split PR from https://github.com/apache/spark/pull/48499 so that
we divide the reasonings for PRs.
### Does this PR introduce _any_ user-facing change?
Yes, new expressions added.
### How was this patch tested?
Tests added.
### Was this patch authored or co-authored using generative AI tooling?
No.
Closes #48580 from mihailom-db/addTryConv-TryMakeInterval.
Authored-by: Mihailo Milosevic <[email protected]>
Signed-off-by: Max Gekk <[email protected]>
---
.../apache/spark/sql/PlanGenerationTestSuite.scala | 41 ++++++
docs/sql-ref-ansi-compliance.md | 2 +-
.../source/reference/pyspark.sql/functions.rst | 1 +
python/pyspark/sql/connect/functions/builtin.py | 25 ++++
python/pyspark/sql/functions/builtin.py | 156 +++++++++++++++++++++
python/pyspark/sql/tests/test_functions.py | 5 +
.../scala/org/apache/spark/sql/functions.scala | 88 ++++++++++++
.../sql/catalyst/analysis/FunctionRegistry.scala | 1 +
.../catalyst/expressions/intervalExpressions.scala | 83 +++++++++++
.../function_try_make_interval_years.explain | 2 +
...function_try_make_interval_years_months.explain | 2 +
...on_try_make_interval_years_months_weeks.explain | 2 +
...y_make_interval_years_months_weeks_days.explain | 2 +
..._interval_years_months_weeks_days_hours.explain | 2 +
...rval_years_months_weeks_days_hours_mins.explain | 2 +
...years_months_weeks_days_hours_mins_secs.explain | 2 +
.../queries/function_try_make_interval_years.json | 25 ++++
.../function_try_make_interval_years.proto.bin | Bin 0 -> 186 bytes
.../function_try_make_interval_years_months.json | 29 ++++
...nction_try_make_interval_years_months.proto.bin | Bin 0 -> 193 bytes
...ction_try_make_interval_years_months_weeks.json | 33 +++++
..._try_make_interval_years_months_weeks.proto.bin | Bin 0 -> 200 bytes
..._try_make_interval_years_months_weeks_days.json | 37 +++++
...make_interval_years_months_weeks_days.proto.bin | Bin 0 -> 207 bytes
...ake_interval_years_months_weeks_days_hours.json | 41 ++++++
...nterval_years_months_weeks_days_hours.proto.bin | Bin 0 -> 214 bytes
...nterval_years_months_weeks_days_hours_mins.json | 45 ++++++
...al_years_months_weeks_days_hours_mins.proto.bin | Bin 0 -> 221 bytes
...al_years_months_weeks_days_hours_mins_secs.json | 49 +++++++
...ars_months_weeks_days_hours_mins_secs.proto.bin | Bin 0 -> 228 bytes
.../sql-functions/sql-expression-schema.md | 1 +
31 files changed, 675 insertions(+), 1 deletion(-)
diff --git
a/connector/connect/client/jvm/src/test/scala/org/apache/spark/sql/PlanGenerationTestSuite.scala
b/connector/connect/client/jvm/src/test/scala/org/apache/spark/sql/PlanGenerationTestSuite.scala
index a11de64ed61f..1b973ac8ea34 100644
---
a/connector/connect/client/jvm/src/test/scala/org/apache/spark/sql/PlanGenerationTestSuite.scala
+++
b/connector/connect/client/jvm/src/test/scala/org/apache/spark/sql/PlanGenerationTestSuite.scala
@@ -1925,6 +1925,47 @@ class PlanGenerationTestSuite
fn.make_interval()
}
+ functionTest("try_make_interval years months weeks days hours mins secs") {
+ fn.try_make_interval(
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("b"))
+ }
+
+ functionTest("try_make_interval years months weeks days hours mins") {
+ fn.try_make_interval(
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"),
+ fn.col("a"))
+ }
+
+ functionTest("try_make_interval years months weeks days hours") {
+ fn.try_make_interval(fn.col("a"), fn.col("a"), fn.col("a"), fn.col("a"),
fn.col("a"))
+ }
+
+ functionTest("try_make_interval years months weeks days") {
+ fn.try_make_interval(fn.col("a"), fn.col("a"), fn.col("a"), fn.col("a"))
+ }
+
+ functionTest("try_make_interval years months weeks") {
+ fn.try_make_interval(fn.col("a"), fn.col("a"), fn.col("a"))
+ }
+
+ functionTest("try_make_interval years months") {
+ fn.try_make_interval(fn.col("a"), fn.col("a"))
+ }
+
+ functionTest("try_make_interval years") {
+ fn.try_make_interval(fn.col("a"))
+ }
+
functionTest("make_timestamp with timezone") {
fn.make_timestamp(
fn.col("a"),
diff --git a/docs/sql-ref-ansi-compliance.md b/docs/sql-ref-ansi-compliance.md
index 268f5b970d30..e05c33509400 100644
--- a/docs/sql-ref-ansi-compliance.md
+++ b/docs/sql-ref-ansi-compliance.md
@@ -383,7 +383,7 @@ When ANSI mode is on, it throws exceptions for invalid
operations. You can use t
- `try_make_timestamp`: identical to the function `make_timestamp`, except
that it returns `NULL` result instead of throwing an exception on error.
- `try_make_timestamp_ltz`: identical to the function `make_timestamp_ltz`,
except that it returns `NULL` result instead of throwing an exception on error.
- `try_make_timestamp_ntz`: identical to the function `make_timestamp_ntz`,
except that it returns `NULL` result instead of throwing an exception on error.
-
+ - `try_make_interval`: identical to the function `make_interval`, except
that it returns `NULL` result instead of throwing an exception on invalid
interval.
### SQL Keywords (optional, disabled by default)
diff --git a/python/docs/source/reference/pyspark.sql/functions.rst
b/python/docs/source/reference/pyspark.sql/functions.rst
index b9df5691b82a..430e353dd701 100644
--- a/python/docs/source/reference/pyspark.sql/functions.rst
+++ b/python/docs/source/reference/pyspark.sql/functions.rst
@@ -301,6 +301,7 @@ Date and Timestamp Functions
to_unix_timestamp
to_utc_timestamp
trunc
+ try_make_interval
try_make_timestamp
try_make_timestamp_ltz
try_make_timestamp_ntz
diff --git a/python/pyspark/sql/connect/functions/builtin.py
b/python/pyspark/sql/connect/functions/builtin.py
index 0c1fd63de5c9..fa1a81ab04eb 100644
--- a/python/pyspark/sql/connect/functions/builtin.py
+++ b/python/pyspark/sql/connect/functions/builtin.py
@@ -3714,6 +3714,31 @@ def make_dt_interval(
make_dt_interval.__doc__ = pysparkfuncs.make_dt_interval.__doc__
+def try_make_interval(
+ years: Optional["ColumnOrName"] = None,
+ months: Optional["ColumnOrName"] = None,
+ weeks: Optional["ColumnOrName"] = None,
+ days: Optional["ColumnOrName"] = None,
+ hours: Optional["ColumnOrName"] = None,
+ mins: Optional["ColumnOrName"] = None,
+ secs: Optional["ColumnOrName"] = None,
+) -> Column:
+ _years = lit(0) if years is None else _to_col(years)
+ _months = lit(0) if months is None else _to_col(months)
+ _weeks = lit(0) if weeks is None else _to_col(weeks)
+ _days = lit(0) if days is None else _to_col(days)
+ _hours = lit(0) if hours is None else _to_col(hours)
+ _mins = lit(0) if mins is None else _to_col(mins)
+ _secs = lit(decimal.Decimal(0)) if secs is None else _to_col(secs)
+
+ return _invoke_function_over_columns(
+ "try_make_interval", _years, _months, _weeks, _days, _hours, _mins,
_secs
+ )
+
+
+try_make_interval.__doc__ = pysparkfuncs.try_make_interval.__doc__
+
+
def make_interval(
years: Optional["ColumnOrName"] = None,
months: Optional["ColumnOrName"] = None,
diff --git a/python/pyspark/sql/functions/builtin.py
b/python/pyspark/sql/functions/builtin.py
index 1ee5c357bd6e..842fdf7ae423 100644
--- a/python/pyspark/sql/functions/builtin.py
+++ b/python/pyspark/sql/functions/builtin.py
@@ -21850,6 +21850,162 @@ def make_dt_interval(
return _invoke_function_over_columns("make_dt_interval", _days, _hours,
_mins, _secs)
+@_try_remote_functions
+def try_make_interval(
+ years: Optional["ColumnOrName"] = None,
+ months: Optional["ColumnOrName"] = None,
+ weeks: Optional["ColumnOrName"] = None,
+ days: Optional["ColumnOrName"] = None,
+ hours: Optional["ColumnOrName"] = None,
+ mins: Optional["ColumnOrName"] = None,
+ secs: Optional["ColumnOrName"] = None,
+) -> Column:
+ """
+ This is a special version of `make_interval` that performs the same
operation, but returns a
+ NULL value instead of raising an error if interval cannot be created.
+
+ .. versionadded:: 4.0.0
+
+ Parameters
+ ----------
+ years : :class:`~pyspark.sql.Column` or str, optional
+ The number of years, positive or negative.
+ months : :class:`~pyspark.sql.Column` or str, optional
+ The number of months, positive or negative.
+ weeks : :class:`~pyspark.sql.Column` or str, optional
+ The number of weeks, positive or negative.
+ days : :class:`~pyspark.sql.Column` or str, optional
+ The number of days, positive or negative.
+ hours : :class:`~pyspark.sql.Column` or str, optional
+ The number of hours, positive or negative.
+ mins : :class:`~pyspark.sql.Column` or str, optional
+ The number of minutes, positive or negative.
+ secs : :class:`~pyspark.sql.Column` or str, optional
+ The number of seconds with the fractional part in microsecond
precision.
+
+ Returns
+ -------
+ :class:`~pyspark.sql.Column`
+ A new column that contains an interval.
+
+ Examples
+ --------
+
+ Example 1: Try make interval from years, months, weeks, days, hours, mins
and secs.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(
+ ... df.year, df.month, df.week, df.day, df.hour, df.min, df.sec)
+ ... ).show(truncate=False)
+ +---------------------------------------------------------------+
+ |try_make_interval(year, month, week, day, hour, min, sec) |
+ +---------------------------------------------------------------+
+ |100 years 11 months 8 days 12 hours 30 minutes 1.001001 seconds|
+ +---------------------------------------------------------------+
+
+ Example 2: Try make interval from years, months, weeks, days, hours and
mins.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(
+ ... df.year, df.month, df.week, df.day, df.hour, df.min)
+ ... ).show(truncate=False)
+ +-------------------------------------------------------+
+ |try_make_interval(year, month, week, day, hour, min, 0)|
+ +-------------------------------------------------------+
+ |100 years 11 months 8 days 12 hours 30 minutes |
+ +-------------------------------------------------------+
+
+ Example 3: Try make interval from years, months, weeks, days and hours.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(
+ ... df.year, df.month, df.week, df.day, df.hour)
+ ... ).show(truncate=False)
+ +-----------------------------------------------------+
+ |try_make_interval(year, month, week, day, hour, 0, 0)|
+ +-----------------------------------------------------+
+ |100 years 11 months 8 days 12 hours |
+ +-----------------------------------------------------+
+
+ Example 4: Try make interval from years, months, weeks and days.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(df.year, df.month, df.week,
df.day)).show(truncate=False)
+ +--------------------------------------------------+
+ |try_make_interval(year, month, week, day, 0, 0, 0)|
+ +--------------------------------------------------+
+ |100 years 11 months 8 days |
+ +--------------------------------------------------+
+
+ Example 5: Try make interval from years, months and weeks.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(df.year, df.month,
df.week)).show(truncate=False)
+ +------------------------------------------------+
+ |try_make_interval(year, month, week, 0, 0, 0, 0)|
+ +------------------------------------------------+
+ |100 years 11 months 7 days |
+ +------------------------------------------------+
+
+ Example 6: Try make interval from years and months.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(df.year, df.month)).show(truncate=False)
+ +---------------------------------------------+
+ |try_make_interval(year, month, 0, 0, 0, 0, 0)|
+ +---------------------------------------------+
+ |100 years 11 months |
+ +---------------------------------------------+
+
+ Example 7: Try make interval from years.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[100, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(df.year)).show(truncate=False)
+ +-----------------------------------------+
+ |try_make_interval(year, 0, 0, 0, 0, 0, 0)|
+ +-----------------------------------------+
+ |100 years |
+ +-----------------------------------------+
+
+ Example 8: Try make interval from years with overflow.
+
+ >>> import pyspark.sql.functions as sf
+ >>> df = spark.createDataFrame([[2147483647, 11, 1, 1, 12, 30, 01.001001]],
+ ... ["year", "month", "week", "day", "hour", "min", "sec"])
+ >>> df.select(sf.try_make_interval(df.year)).show(truncate=False)
+ +-----------------------------------------+
+ |try_make_interval(year, 0, 0, 0, 0, 0, 0)|
+ +-----------------------------------------+
+ |NULL |
+ +-----------------------------------------+
+
+ """
+ _years = lit(0) if years is None else years
+ _months = lit(0) if months is None else months
+ _weeks = lit(0) if weeks is None else weeks
+ _days = lit(0) if days is None else days
+ _hours = lit(0) if hours is None else hours
+ _mins = lit(0) if mins is None else mins
+ _secs = lit(decimal.Decimal(0)) if secs is None else secs
+ return _invoke_function_over_columns(
+ "try_make_interval", _years, _months, _weeks, _days, _hours, _mins,
_secs
+ )
+
+
@_try_remote_functions
def make_interval(
years: Optional["ColumnOrName"] = None,
diff --git a/python/pyspark/sql/tests/test_functions.py
b/python/pyspark/sql/tests/test_functions.py
index 74e043ca1e6e..cf8f685ea449 100644
--- a/python/pyspark/sql/tests/test_functions.py
+++ b/python/pyspark/sql/tests/test_functions.py
@@ -452,6 +452,11 @@ class FunctionsTestsMixin:
actual = df.select(F.collation(F.collate("name",
"UNICODE"))).distinct().collect()
self.assertEqual([Row("UNICODE")], actual)
+ def test_try_make_interval(self):
+ df = self.spark.createDataFrame([(2147483647,)], ["num"])
+ actual = df.select(F.isnull(F.try_make_interval("num"))).collect()
+ self.assertEqual([Row(True)], actual)
+
def test_octet_length_function(self):
# SPARK-36751: add octet length api for python
df = self.spark.createDataFrame([("cat",), ("\U0001F408",)], ["cat"])
diff --git a/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
b/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
index 35453603de5d..2a04212ee258 100644
--- a/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
+++ b/sql/api/src/main/scala/org/apache/spark/sql/functions.scala
@@ -8005,6 +8005,23 @@ object functions {
def make_dt_interval(): Column =
Column.fn("make_dt_interval")
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(
+ years: Column,
+ months: Column,
+ weeks: Column,
+ days: Column,
+ hours: Column,
+ mins: Column,
+ secs: Column): Column =
+ Column.fn("try_make_interval", years, months, weeks, days, hours, mins,
secs)
+
/**
* Make interval from years, months, weeks, days, hours, mins and secs.
*
@@ -8021,6 +8038,22 @@ object functions {
secs: Column): Column =
Column.fn("make_interval", years, months, weeks, days, hours, mins, secs)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(
+ years: Column,
+ months: Column,
+ weeks: Column,
+ days: Column,
+ hours: Column,
+ mins: Column): Column =
+ Column.fn("try_make_interval", years, months, weeks, days, hours, mins)
+
/**
* Make interval from years, months, weeks, days, hours and mins.
*
@@ -8036,6 +8069,21 @@ object functions {
mins: Column): Column =
Column.fn("make_interval", years, months, weeks, days, hours, mins)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(
+ years: Column,
+ months: Column,
+ weeks: Column,
+ days: Column,
+ hours: Column): Column =
+ Column.fn("try_make_interval", years, months, weeks, days, hours)
+
/**
* Make interval from years, months, weeks, days and hours.
*
@@ -8050,6 +8098,16 @@ object functions {
hours: Column): Column =
Column.fn("make_interval", years, months, weeks, days, hours)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(years: Column, months: Column, weeks: Column, days:
Column): Column =
+ Column.fn("try_make_interval", years, months, weeks, days)
+
/**
* Make interval from years, months, weeks and days.
*
@@ -8059,6 +8117,16 @@ object functions {
def make_interval(years: Column, months: Column, weeks: Column, days:
Column): Column =
Column.fn("make_interval", years, months, weeks, days)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(years: Column, months: Column, weeks: Column): Column =
+ Column.fn("try_make_interval", years, months, weeks)
+
/**
* Make interval from years, months and weeks.
*
@@ -8068,6 +8136,16 @@ object functions {
def make_interval(years: Column, months: Column, weeks: Column): Column =
Column.fn("make_interval", years, months, weeks)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(years: Column, months: Column): Column =
+ Column.fn("try_make_interval", years, months)
+
/**
* Make interval from years and months.
*
@@ -8077,6 +8155,16 @@ object functions {
def make_interval(years: Column, months: Column): Column =
Column.fn("make_interval", years, months)
+ /**
+ * This is a special version of `make_interval` that performs the same
operation, but returns a
+ * NULL value instead of raising an error if interval cannot be created.
+ *
+ * @group datetime_funcs
+ * @since 4.0.0
+ */
+ def try_make_interval(years: Column): Column =
+ Column.fn("try_make_interval", years)
+
/**
* Make interval from years.
*
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
index 8fe5c1b59902..5103f8048856 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
@@ -466,6 +466,7 @@ object FunctionRegistry {
expression[TryAesDecrypt]("try_aes_decrypt"),
expression[TryReflect]("try_reflect"),
expression[TryUrlDecode]("try_url_decode"),
+ expression[TryMakeInterval]("try_make_interval"),
// aggregate functions
expression[HyperLogLogPlusPlus]("approx_count_distinct"),
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/intervalExpressions.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/intervalExpressions.scala
index d18630f54202..5363f1bba390 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/intervalExpressions.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/intervalExpressions.scala
@@ -224,6 +224,89 @@ case class DivideInterval(
copy(interval = newLeft, num = newRight)
}
+// scalastyle:off line.size.limit
+@ExpressionDescription(
+ usage = "_FUNC_([years[, months[, weeks[, days[, hours[, mins[, secs]]]]]]])
- This is a special version of `make_interval` that performs the same
operation, but returns NULL when an overflow occurs.",
+ arguments = """
+ Arguments:
+ * years - the number of years, positive or negative
+ * months - the number of months, positive or negative
+ * weeks - the number of weeks, positive or negative
+ * days - the number of days, positive or negative
+ * hours - the number of hours, positive or negative
+ * mins - the number of minutes, positive or negative
+ * secs - the number of seconds with the fractional part in microsecond
precision.
+ """,
+ examples = """
+ Examples:
+ > SELECT _FUNC_(100, 11, 1, 1, 12, 30, 01.001001);
+ 100 years 11 months 8 days 12 hours 30 minutes 1.001001 seconds
+ > SELECT _FUNC_(100, null, 3);
+ NULL
+ > SELECT _FUNC_(0, 1, 0, 1, 0, 0, 100.000001);
+ 1 months 1 days 1 minutes 40.000001 seconds
+ > SELECT _FUNC_(2147483647);
+ NULL
+ """,
+ since = "4.0.0",
+ group = "datetime_funcs")
+// scalastyle:on line.size.limit
+case class TryMakeInterval(
+ years: Expression,
+ months: Expression,
+ weeks: Expression,
+ days: Expression,
+ hours: Expression,
+ mins: Expression,
+ secs: Expression,
+ replacement: Expression)
+ extends RuntimeReplaceable with InheritAnalysisRules {
+
+ def this(
+ years: Expression,
+ months: Expression,
+ weeks: Expression,
+ days: Expression,
+ hours: Expression,
+ mins: Expression,
+ secs: Expression) =
+ this(years, months, weeks, days, hours, mins, secs,
+ MakeInterval(years, months, weeks, days, hours, mins, secs, failOnError
= false))
+
+ def this(
+ years: Expression,
+ months: Expression,
+ weeks: Expression,
+ days: Expression,
+ hours: Expression,
+ mins: Expression) =
+ this(years, months, weeks, days, hours, mins, Literal(Decimal(0,
Decimal.MAX_LONG_DIGITS, 6)))
+
+ def this(
+ years: Expression,
+ months: Expression,
+ weeks: Expression,
+ days: Expression,
+ hours: Expression) = {
+ this(years, months, weeks, days, hours, Literal(0))
+ }
+ def this(years: Expression, months: Expression, weeks: Expression, days:
Expression) =
+ this(years, months, weeks, days, Literal(0))
+ def this(years: Expression, months: Expression, weeks: Expression) =
+ this(years, months, weeks, Literal(0))
+ def this(years: Expression, months: Expression) = this(years, months,
Literal(0))
+ def this(years: Expression) = this(years, Literal(0))
+ // We do not support this() in try version of the function, as it will never
return overflow
+
+ override protected def withNewChildInternal(newChild: Expression):
Expression = {
+ copy(replacement = newChild)
+ }
+
+ override def parameters: Seq[Expression] = Seq(years, months, weeks, days,
hours, mins, secs)
+
+ override def prettyName: String = "try_make_interval"
+}
+
// scalastyle:off line.size.limit
@ExpressionDescription(
usage = "_FUNC_([years[, months[, weeks[, days[, hours[, mins[, secs]]]]]]])
- Make interval from years, months, weeks, days, hours, mins and secs.",
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years.explain
new file mode 100644
index 000000000000..862363f90fa2
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, 0, 0, 0, 0, 0, 0.000000, false) AS
try_make_interval(a, 0, 0, 0, 0, 0, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months.explain
new file mode 100644
index 000000000000..9b60a8e0ce84
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, 0, 0, 0, 0, 0.000000, false) AS
try_make_interval(a, a, 0, 0, 0, 0, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks.explain
new file mode 100644
index 000000000000..409a2a520626
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, a#0, 0, 0, 0, 0.000000, false) AS
try_make_interval(a, a, a, 0, 0, 0, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days.explain
new file mode 100644
index 000000000000..347379a63397
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, a#0, a#0, 0, 0, 0.000000, false) AS
try_make_interval(a, a, a, a, 0, 0, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours.explain
new file mode 100644
index 000000000000..99e1e3d2a419
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, a#0, a#0, a#0, 0, 0.000000, false) AS
try_make_interval(a, a, a, a, a, 0, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins.explain
new file mode 100644
index 000000000000..af6441b08ad9
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, a#0, a#0, a#0, a#0, 0.000000, false) AS
try_make_interval(a, a, a, a, a, a, 0.000000)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins_secs.explain
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins_secs.explain
new file mode 100644
index 000000000000..4af5fd680836
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/explain-results/function_try_make_interval_years_months_weeks_days_hours_mins_secs.explain
@@ -0,0 +1,2 @@
+Project [make_interval(a#0, a#0, a#0, a#0, a#0, a#0, cast(b#0 as
decimal(18,6)), false) AS try_make_interval(a, a, a, a, a, a, b)#0]
++- LocalRelation <empty>, [id#0L, a#0, b#0, d#0, e#0, f#0, g#0]
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.json
new file mode 100644
index 000000000000..a7a234849604
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.json
@@ -0,0 +1,25 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.proto.bin
new file mode 100644
index 000000000000..d459b6e8ec67
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.json
new file mode 100644
index 000000000000..14aaa41ee2cb
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.json
@@ -0,0 +1,29 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.proto.bin
new file mode 100644
index 000000000000..5123b995417b
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.json
new file mode 100644
index 000000000000..a6ac2f27e3dc
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.json
@@ -0,0 +1,33 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.proto.bin
new file mode 100644
index 000000000000..cecfca97f7e2
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.json
new file mode 100644
index 000000000000..c9d4f1d4d2f1
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.json
@@ -0,0 +1,37 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.proto.bin
new file mode 100644
index 000000000000..423172405c39
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.json
new file mode 100644
index 000000000000..7f2a42f01db4
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.json
@@ -0,0 +1,41 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.proto.bin
new file mode 100644
index 000000000000..71259b402aa5
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.json
new file mode 100644
index 000000000000..35ab05a90b3c
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.json
@@ -0,0 +1,45 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.proto.bin
new file mode 100644
index 000000000000..f8cf29d15aab
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins.proto.bin
differ
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.json
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.json
new file mode 100644
index 000000000000..2f9c1d019359
--- /dev/null
+++
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.json
@@ -0,0 +1,49 @@
+{
+ "common": {
+ "planId": "1"
+ },
+ "project": {
+ "input": {
+ "common": {
+ "planId": "0"
+ },
+ "localRelation": {
+ "schema":
"struct\u003cid:bigint,a:int,b:double,d:struct\u003cid:bigint,a:int,b:double\u003e,e:array\u003cint\u003e,f:map\u003cstring,struct\u003cid:bigint,a:int,b:double\u003e\u003e,g:string\u003e"
+ }
+ },
+ "expressions": [{
+ "unresolvedFunction": {
+ "functionName": "try_make_interval",
+ "arguments": [{
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "a"
+ }
+ }, {
+ "unresolvedAttribute": {
+ "unparsedIdentifier": "b"
+ }
+ }]
+ }
+ }]
+ }
+}
\ No newline at end of file
diff --git
a/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.proto.bin
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.proto.bin
new file mode 100644
index 000000000000..d7343a059b53
Binary files /dev/null and
b/sql/connect/common/src/test/resources/query-tests/queries/function_try_make_interval_years_months_weeks_days_hours_mins_secs.proto.bin
differ
diff --git a/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
b/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
index 27d9367c49e9..c54e09735a9b 100644
--- a/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
+++ b/sql/core/src/test/resources/sql-functions/sql-expression-schema.md
@@ -354,6 +354,7 @@
| org.apache.spark.sql.catalyst.expressions.TryAesDecrypt | try_aes_decrypt |
SELECT
try_aes_decrypt(unhex('6E7CA17BBB468D3084B5744BCA729FB7B2B7BCB8E4472847D02670489D95FA97DBBA7D3210'),
'0000111122223333', 'GCM') |
struct<try_aes_decrypt(unhex(6E7CA17BBB468D3084B5744BCA729FB7B2B7BCB8E4472847D02670489D95FA97DBBA7D3210),
0000111122223333, GCM, DEFAULT, ):binary> |
| org.apache.spark.sql.catalyst.expressions.TryDivide | try_divide | SELECT
try_divide(3, 2) | struct<try_divide(3, 2):double> |
| org.apache.spark.sql.catalyst.expressions.TryElementAt | try_element_at |
SELECT try_element_at(array(1, 2, 3), 2) | struct<try_element_at(array(1, 2,
3), 2):int> |
+| org.apache.spark.sql.catalyst.expressions.TryMakeInterval |
try_make_interval | SELECT try_make_interval(100, 11, 1, 1, 12, 30, 01.001001)
| struct<try_make_interval(100, 11, 1, 1, 12, 30, 1.001001):interval> |
| org.apache.spark.sql.catalyst.expressions.TryMakeTimestamp |
try_make_timestamp | SELECT try_make_timestamp(2014, 12, 28, 6, 30, 45.887) |
struct<try_make_timestamp(2014, 12, 28, 6, 30, 45.887):timestamp> |
|
org.apache.spark.sql.catalyst.expressions.TryMakeTimestampLTZExpressionBuilder
| try_make_timestamp_ltz | SELECT try_make_timestamp_ltz(2014, 12, 28, 6, 30,
45.887) | struct<try_make_timestamp_ltz(2014, 12, 28, 6, 30, 45.887):timestamp>
|
|
org.apache.spark.sql.catalyst.expressions.TryMakeTimestampNTZExpressionBuilder
| try_make_timestamp_ntz | SELECT try_make_timestamp_ntz(2014, 12, 28, 6, 30,
45.887) | struct<try_make_timestamp_ntz(2014, 12, 28, 6, 30,
45.887):timestamp_ntz> |
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]