-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-10439] [sql] Add bound checks to DateTimeUtils. #8606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
ffe39e4
196ba9e
63d0c39
00757d2
edeb06e
922c09e
3869816
6064ef2
7a4cf9e
fa8d6f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |
|
|
||
| package org.apache.spark.sql.catalyst.util | ||
|
|
||
| import java.lang.{Long => JLong} | ||
| import java.sql.{Date, Timestamp} | ||
| import java.text.{DateFormat, SimpleDateFormat} | ||
| import java.util.{TimeZone, Calendar} | ||
|
|
@@ -56,6 +57,13 @@ object DateTimeUtils { | |
|
|
||
| @transient lazy val defaultTimeZone = TimeZone.getDefault | ||
|
|
||
| // Constants defining the allowed ranges for timestamps that can be parsed by java.sql.Timestamp. | ||
| // Limits are calculated based on UTC. | ||
| private[spark] final val MIN_TIMESTAMP: Long = | ||
| Timestamp.valueOf("0001-01-01 00:00:00").getTime() + defaultTimeZone.getRawOffset() | ||
| private[spark] final val MAX_TIMESTAMP: Long = | ||
| Timestamp.valueOf("9999-12-31 23:59:59.999999").getTime() + defaultTimeZone.getRawOffset() | ||
|
|
||
| // Java TimeZone has no mention of thread safety. Use thread local instance to be safe. | ||
| private val threadLocalLocalTimeZone = new ThreadLocal[TimeZone] { | ||
| override protected def initialValue: TimeZone = { | ||
|
|
@@ -172,6 +180,8 @@ object DateTimeUtils { | |
| */ | ||
| def fromJavaTimestamp(t: Timestamp): SQLTimestamp = { | ||
| if (t != null) { | ||
| require(t.getTime() <= JLong.MAX_VALUE / 1000 && t.getTime() >= JLong.MIN_VALUE / 1000, | ||
| s"Timestamp exceeds allowed range (${t.getTime()}).") | ||
| t.getTime() * 1000L + (t.getNanos().toLong / 1000) % 1000L | ||
| } else { | ||
| 0L | ||
|
|
@@ -193,9 +203,14 @@ object DateTimeUtils { | |
| */ | ||
| def toJulianDay(us: SQLTimestamp): (Int, Long) = { | ||
| val seconds = us / MICROS_PER_SECOND | ||
| val day = seconds / SECONDS_PER_DAY + JULIAN_DAY_OF_EPOCH | ||
| val secondsInDay = seconds % SECONDS_PER_DAY | ||
| val nanos = (us % MICROS_PER_SECOND) * 1000L | ||
| var day = seconds / SECONDS_PER_DAY + JULIAN_DAY_OF_EPOCH | ||
| var secondsInDay = seconds % SECONDS_PER_DAY | ||
| var nanos = (us % MICROS_PER_SECOND) * 1000L | ||
| if (us < 0) { | ||
| day -= 1 | ||
| secondsInDay += SECONDS_PER_DAY | ||
| nanos += (SECONDS_PER_DAY * MICROS_PER_SECOND * 1000L) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not correct, it should be:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch; my code can return
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created https://issues.apache.org/jira/browse/SPARK-10522 for this, then we could back port the fix for 1.5. |
||
| } | ||
| (day.toInt, secondsInDay * NANOS_PER_SECOND + nanos) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!