MaxGekk commented on a change in pull request #32271:
URL: https://github.com/apache/spark/pull/32271#discussion_r624513412
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
##########
@@ -1362,6 +1368,12 @@ abstract class CastBase extends UnaryExpression with
TimeZoneAwareExpression wit
}
+ private[this] def castToDayTimeIntervalCode(from: DataType): CastFunction =
from match {
+ case StringType =>
+ val util = IntervalUtils.getClass.getCanonicalName.stripSuffix("$")
+ (c, evPrim, evNull) => code"$evPrim = $util.castStringToDTInterval($c);"
Review comment:
nit: `evNull` is unused one
```suggestion
(c, evPrim, _) => code"$evPrim = $util.castStringToDTInterval($c);"
```
##########
File path:
sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
##########
@@ -1775,6 +1775,48 @@ class CastSuite extends CastSuiteBase {
}
}
+ test("SPARK-35112: Cast string to day-time interval") {
+ checkEvaluation(cast(Literal.create("0 0:0:0"), DayTimeIntervalType), 0L)
+ checkEvaluation(cast(Literal.create("INTERVAL '0 0:0:0' DAY TO SECOND"),
Review comment:
Could you check `INTERVAL` in lower case + spaces:
```suggestion
checkEvaluation(cast(Literal.create(" interval '0 0:0:0' Day TO second
"),
```
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/IntervalUtils.scala
##########
@@ -150,6 +150,57 @@ object IntervalUtils {
}
}
+ private val daySecondStringPattern = ("(?i)^(INTERVAL\\s+)([+|-])?(')" +
+ "([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?(')(\\s+DAY\\s+TO\\s+SECOND)$").r
+ private val daySecondPattern = "^([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?$".r
Review comment:
Let's extract the common pattern:
```suggestion
private val unquotedDaySecondPattern =
"([+|-])?(\\d+) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?"
private val quotedDaySecondPattern = (s"^$unquotedDaySecondPattern$$").r
private val daySecondLiteralPattern =
(s"(?i)^(INTERVAL\\s+)([+|-])?(')$unquotedDaySecondPattern(')(\\s+DAY\\s+TO\\s+SECOND)$$").r
```
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/IntervalUtils.scala
##########
@@ -150,6 +150,57 @@ object IntervalUtils {
}
}
+ private val daySecondStringPattern = ("(?i)^(INTERVAL\\s+)([+|-])?(')" +
+ "([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?(')(\\s+DAY\\s+TO\\s+SECOND)$").r
+ private val daySecondPattern = "^([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?$".r
+
+ def castStringToDTInterval(input: UTF8String): Long = {
+ def secondAndMicro(second: String, micro: String): String = {
+ if (micro != null) {
+ s"$second$micro"
+ } else {
+ second
+ }
+ }
+ val intervalStr = input.trimAll().toString
+ intervalStr match {
Review comment:
Just inline it:
```suggestion
input.trimAll().toString match {
```
##########
File path:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/IntervalUtils.scala
##########
@@ -150,6 +150,57 @@ object IntervalUtils {
}
}
+ private val daySecondStringPattern = ("(?i)^(INTERVAL\\s+)([+|-])?(')" +
+ "([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?(')(\\s+DAY\\s+TO\\s+SECOND)$").r
+ private val daySecondPattern = "^([+|-])?(\\d+)
(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(\\.\\d{1,9})?$".r
+
+ def castStringToDTInterval(input: UTF8String): Long = {
+ def secondAndMicro(second: String, micro: String): String = {
+ if (micro != null) {
+ s"$second$micro"
+ } else {
+ second
+ }
+ }
+ val intervalStr = input.trimAll().toString
+ intervalStr match {
+ case daySecondPattern("-", day, hour, minute, second, micro) =>
+ toDTInterval(day, hour, minute, secondAndMicro(second, micro), -1)
+ case daySecondPattern(_, day, hour, minute, second, micro) =>
+ toDTInterval(day, hour, minute, secondAndMicro(second, micro), 1)
+ case daySecondStringPattern(
+ _, firstSign, _, secondSign, day, hour, minute, second, micro, _, _) =>
Review comment:
You don't need to put quotes to groups:
```suggestion
case daySecondLiteralPattern(firstSign, _, secondSign, day, hour,
minute, second, micro) =>
```
if you change the pattern to:
```
private val daySecondLiteralPattern =
(s"(?i)^(INTERVAL\\s+)([+|-])?\\'$unquotedDaySecondPattern\\'\\s+DAY\\s+TO\\s+SECOND$$").r
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]