[SPARK-31771][SQL] Disable Narrow TextStyle for datetime pattern 'G/M/L/E/u/Q/q'
### What changes were proposed in this pull request? Five continuous pattern characters with 'G/M/L/E/u/Q/q' means Narrow-Text Style while we turn to use `java.time.DateTimeFormatterBuilder` since 3.0.0, which output the leading single letter of the value, e.g. `December` would be `D`. In Spark 2.4 they mean Full-Text Style. In this PR, we explicitly disable Narrow-Text Style for these pattern characters. ### Why are the changes needed? Without this change, there will be a silent data change. ### Does this PR introduce _any_ user-facing change? Yes, queries with datetime operations using datetime patterns, e.g. `G/M/L/E/u` will fail if the pattern length is 5 and other patterns, e,g. 'k', 'm' also can accept a certain number of letters. 1. datetime patterns that are not supported by the new parser but the legacy will get SparkUpgradeException, e.g. "GGGGG", "MMMMM", "LLLLL", "EEEEE", "uuuuu", "aa", "aaa". 2 options are given to end-users, one is to use legacy mode, and the other is to follow the new online doc for correct datetime patterns 2, datetime patterns that are not supported by both the new parser and the legacy, e.g. "QQQQQ", "qqqqq", will get IllegalArgumentException which is captured by Spark internally and results NULL to end-users. ### How was this patch tested? add unit tests Closes #28592 from yaooqinn/SPARK-31771. Authored-by: Kent Yao <yaooqinn@hotmail.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
This commit is contained in:
parent
92685c0148
commit
695cb617d4
|
@ -30,25 +30,25 @@ Spark uses pattern letters in the following table for date and timestamp parsing
|
||||||
|
|
||||||
|Symbol|Meaning|Presentation|Examples|
|
|Symbol|Meaning|Presentation|Examples|
|
||||||
|------|-------|------------|--------|
|
|------|-------|------------|--------|
|
||||||
|**G**|era|text|AD; Anno Domini; A|
|
|**G**|era|text|AD; Anno Domini|
|
||||||
|**y**|year|year|2020; 20|
|
|**y**|year|year|2020; 20|
|
||||||
|**D**|day-of-year|number|189|
|
|**D**|day-of-year|number(3)|189|
|
||||||
|**M/L**|month-of-year|number/text|7; 07; Jul; July; J|
|
|**M/L**|month-of-year|month|7; 07; Jul; July|
|
||||||
|**d**|day-of-month|number|28|
|
|**d**|day-of-month|number(3)|28|
|
||||||
|**Q/q**|quarter-of-year|number/text|3; 03; Q3; 3rd quarter|
|
|**Q/q**|quarter-of-year|number/text|3; 03; Q3; 3rd quarter|
|
||||||
|**Y**|week-based-year|year|1996; 96|
|
|**Y**|week-based-year|year|1996; 96|
|
||||||
|**w**|week-of-week-based-year|number|27|
|
|**w**|week-of-week-based-year|number(2)|27|
|
||||||
|**W**|week-of-month|number|4|
|
|**W**|week-of-month|number(1)|4|
|
||||||
|**E**|day-of-week|text|Tue; Tuesday; T|
|
|**E**|day-of-week|text|Tue; Tuesday|
|
||||||
|**u**|localized day-of-week|number/text|2; 02; Tue; Tuesday; T|
|
|**u**|localized day-of-week|number/text|2; 02; Tue; Tuesday|
|
||||||
|**F**|week-of-month|number|3|
|
|**F**|week-of-month|number(1)|3|
|
||||||
|**a**|am-pm-of-day|text|PM|
|
|**a**|am-pm-of-day|am-pm|PM|
|
||||||
|**h**|clock-hour-of-am-pm (1-12)|number|12|
|
|**h**|clock-hour-of-am-pm (1-12)|number(2)|12|
|
||||||
|**K**|hour-of-am-pm (0-11)|number|0|
|
|**K**|hour-of-am-pm (0-11)|number(2)|0|
|
||||||
|**k**|clock-hour-of-day (1-24)|number|0|
|
|**k**|clock-hour-of-day (1-24)|number(2)|0|
|
||||||
|**H**|hour-of-day (0-23)|number|0|
|
|**H**|hour-of-day (0-23)|number(2)|0|
|
||||||
|**m**|minute-of-hour|number|30|
|
|**m**|minute-of-hour|number(2)|30|
|
||||||
|**s**|second-of-minute|number|55|
|
|**s**|second-of-minute|number(2)|55|
|
||||||
|**S**|fraction-of-second|fraction|978|
|
|**S**|fraction-of-second|fraction|978|
|
||||||
|**V**|time-zone ID|zone-id|America/Los_Angeles; Z; -08:30|
|
|**V**|time-zone ID|zone-id|America/Los_Angeles; Z; -08:30|
|
||||||
|**z**|time-zone name|zone-name|Pacific Standard Time; PST|
|
|**z**|time-zone name|zone-name|Pacific Standard Time; PST|
|
||||||
|
@ -63,9 +63,9 @@ Spark uses pattern letters in the following table for date and timestamp parsing
|
||||||
|
|
||||||
The count of pattern letters determines the format.
|
The count of pattern letters determines the format.
|
||||||
|
|
||||||
- Text: The text style is determined based on the number of pattern letters used. Less than 4 pattern letters will use the short form. Exactly 4 pattern letters will use the full form. Exactly 5 pattern letters will use the narrow form. Six or more letters will fail.
|
- Text: The text style is determined based on the number of pattern letters used. Less than 4 pattern letters will use the short form. Exactly 4 pattern letters will use the full form. Exactly 5 pattern letters will use the narrow form. 5 or more letters will fail.
|
||||||
|
|
||||||
- Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary. The following pattern letters have constraints on the count of letters. Only one letter 'F' can be specified. Up to two letters of 'd', 'H', 'h', 'K', 'k', 'm', and 's' can be specified. Up to three letters of 'D' can be specified.
|
- Number(n): The n here represents the maximum count of letters this type of datetime pattern can be used. If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary.
|
||||||
|
|
||||||
- Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. Otherwise use the Number rules above.
|
- Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. Otherwise use the Number rules above.
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ The count of pattern letters determines the format.
|
||||||
|
|
||||||
- Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive. If the count of letters is less than four (but not two), then the sign is only output for negative years. Otherwise, the sign is output if the pad width is exceeded when 'G' is not present.
|
- Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive. If the count of letters is less than four (but not two), then the sign is only output for negative years. Otherwise, the sign is output if the pad width is exceeded when 'G' is not present.
|
||||||
|
|
||||||
- Month: If the number of pattern letters is 3 or more, the month is interpreted as text; otherwise, it is interpreted as a number. The text form is depend on letters - 'M' denotes the 'standard' form, and 'L' is for 'stand-alone' form. The difference between the 'standard' and 'stand-alone' forms is trickier to describe as there is no difference in English. However, in other languages there is a difference in the word used when the text is used alone, as opposed to in a complete date. For example, the word used for a month when used alone in a date picker is different to the word used for month in association with a day and year in a date. In Russian, 'Июль' is the stand-alone form of July, and 'Июля' is the standard form. Here are examples for all supported pattern letters (more than 5 letters is invalid):
|
- Month: If the number of pattern letters is 3 or more, the month is interpreted as text; otherwise, it is interpreted as a number. The text form is depend on letters - 'M' denotes the 'standard' form, and 'L' is for 'stand-alone' form. The difference between the 'standard' and 'stand-alone' forms is trickier to describe as there is no difference in English. However, in other languages there is a difference in the word used when the text is used alone, as opposed to in a complete date. For example, the word used for a month when used alone in a date picker is different to the word used for month in association with a day and year in a date. In Russian, 'Июль' is the stand-alone form of July, and 'Июля' is the standard form. Here are examples for all supported pattern letters (more than 4 letters is invalid):
|
||||||
- `'M'` or `'L'`: Month number in a year starting from 1. There is no difference between 'M' and 'L'. Month from 1 to 9 are printed without padding.
|
- `'M'` or `'L'`: Month number in a year starting from 1. There is no difference between 'M' and 'L'. Month from 1 to 9 are printed without padding.
|
||||||
```sql
|
```sql
|
||||||
spark-sql> select date_format(date '1970-01-01', "M");
|
spark-sql> select date_format(date '1970-01-01', "M");
|
||||||
|
@ -119,13 +119,8 @@ The count of pattern letters determines the format.
|
||||||
spark-sql> select to_csv(named_struct('date', date '1970-01-01'), map('dateFormat', 'LLLL', 'locale', 'RU'));
|
spark-sql> select to_csv(named_struct('date', date '1970-01-01'), map('dateFormat', 'LLLL', 'locale', 'RU'));
|
||||||
январь
|
январь
|
||||||
```
|
```
|
||||||
- `'LLLLL'` or `'MMMMM'`: Narrow textual representation of standard or stand-alone forms. Typically it is a single letter.
|
|
||||||
```sql
|
- am-pm: This outputs the am-pm-of-day. Pattern letter count must be 1.
|
||||||
spark-sql> select date_format(date '1970-07-01', "LLLLL");
|
|
||||||
J
|
|
||||||
spark-sql> select date_format(date '1970-01-01', "MMMMM");
|
|
||||||
J
|
|
||||||
```
|
|
||||||
|
|
||||||
- Zone ID(V): This outputs the display the time-zone ID. Pattern letter count must be 2.
|
- Zone ID(V): This outputs the display the time-zone ID. Pattern letter count must be 2.
|
||||||
|
|
||||||
|
@ -147,5 +142,3 @@ More details for the text style:
|
||||||
- Short Form: Short text, typically an abbreviation. For example, day-of-week Monday might output "Mon".
|
- Short Form: Short text, typically an abbreviation. For example, day-of-week Monday might output "Mon".
|
||||||
|
|
||||||
- Full Form: Full text, typically the full description. For example, day-of-week Monday might output "Monday".
|
- Full Form: Full text, typically the full description. For example, day-of-week Monday might output "Monday".
|
||||||
|
|
||||||
- Narrow Form: Narrow text, typically a single letter. For example, day-of-week Monday might output "M".
|
|
||||||
|
|
|
@ -85,13 +85,13 @@ class UnivocityParser(
|
||||||
// We preallocate it avoid unnecessary allocations.
|
// We preallocate it avoid unnecessary allocations.
|
||||||
private val noRows = None
|
private val noRows = None
|
||||||
|
|
||||||
private val timestampFormatter = TimestampFormatter(
|
private lazy val timestampFormatter = TimestampFormatter(
|
||||||
options.timestampFormat,
|
options.timestampFormat,
|
||||||
options.zoneId,
|
options.zoneId,
|
||||||
options.locale,
|
options.locale,
|
||||||
legacyFormat = FAST_DATE_FORMAT,
|
legacyFormat = FAST_DATE_FORMAT,
|
||||||
needVarLengthSecondFraction = true)
|
needVarLengthSecondFraction = true)
|
||||||
private val dateFormatter = DateFormatter(
|
private lazy val dateFormatter = DateFormatter(
|
||||||
options.dateFormat,
|
options.dateFormat,
|
||||||
options.zoneId,
|
options.zoneId,
|
||||||
options.locale,
|
options.locale,
|
||||||
|
|
|
@ -880,6 +880,7 @@ abstract class ToTimestamp
|
||||||
legacyFormat = SIMPLE_DATE_FORMAT,
|
legacyFormat = SIMPLE_DATE_FORMAT,
|
||||||
needVarLengthSecondFraction = true)
|
needVarLengthSecondFraction = true)
|
||||||
} catch {
|
} catch {
|
||||||
|
case e: SparkUpgradeException => throw e
|
||||||
case NonFatal(_) => null
|
case NonFatal(_) => null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,6 +1062,7 @@ case class FromUnixTime(sec: Expression, format: Expression, timeZoneId: Option[
|
||||||
legacyFormat = SIMPLE_DATE_FORMAT,
|
legacyFormat = SIMPLE_DATE_FORMAT,
|
||||||
needVarLengthSecondFraction = false)
|
needVarLengthSecondFraction = false)
|
||||||
} catch {
|
} catch {
|
||||||
|
case e: SparkUpgradeException => throw e
|
||||||
case NonFatal(_) => null
|
case NonFatal(_) => null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,6 +1078,7 @@ case class FromUnixTime(sec: Expression, format: Expression, timeZoneId: Option[
|
||||||
try {
|
try {
|
||||||
UTF8String.fromString(formatter.format(time.asInstanceOf[Long] * MICROS_PER_SECOND))
|
UTF8String.fromString(formatter.format(time.asInstanceOf[Long] * MICROS_PER_SECOND))
|
||||||
} catch {
|
} catch {
|
||||||
|
case e: SparkUpgradeException => throw e
|
||||||
case NonFatal(_) => null
|
case NonFatal(_) => null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,6 +1096,7 @@ case class FromUnixTime(sec: Expression, format: Expression, timeZoneId: Option[
|
||||||
needVarLengthSecondFraction = false)
|
needVarLengthSecondFraction = false)
|
||||||
.format(time.asInstanceOf[Long] * MICROS_PER_SECOND))
|
.format(time.asInstanceOf[Long] * MICROS_PER_SECOND))
|
||||||
} catch {
|
} catch {
|
||||||
|
case e: SparkUpgradeException => throw e
|
||||||
case NonFatal(_) => null
|
case NonFatal(_) => null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,13 +56,13 @@ class JacksonParser(
|
||||||
|
|
||||||
private val factory = options.buildJsonFactory()
|
private val factory = options.buildJsonFactory()
|
||||||
|
|
||||||
private val timestampFormatter = TimestampFormatter(
|
private lazy val timestampFormatter = TimestampFormatter(
|
||||||
options.timestampFormat,
|
options.timestampFormat,
|
||||||
options.zoneId,
|
options.zoneId,
|
||||||
options.locale,
|
options.locale,
|
||||||
legacyFormat = FAST_DATE_FORMAT,
|
legacyFormat = FAST_DATE_FORMAT,
|
||||||
needVarLengthSecondFraction = true)
|
needVarLengthSecondFraction = true)
|
||||||
private val dateFormatter = DateFormatter(
|
private lazy val dateFormatter = DateFormatter(
|
||||||
options.dateFormat,
|
options.dateFormat,
|
||||||
options.zoneId,
|
options.zoneId,
|
||||||
options.locale,
|
options.locale,
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.spark.sql.catalyst.util
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.{LocalDate, ZoneId}
|
import java.time.{LocalDate, ZoneId}
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.{Date, Locale}
|
import java.util.{Date, Locale}
|
||||||
|
|
||||||
import org.apache.commons.lang3.time.FastDateFormat
|
import org.apache.commons.lang3.time.FastDateFormat
|
||||||
|
@ -33,6 +34,8 @@ sealed trait DateFormatter extends Serializable {
|
||||||
def format(days: Int): String
|
def format(days: Int): String
|
||||||
def format(date: Date): String
|
def format(date: Date): String
|
||||||
def format(localDate: LocalDate): String
|
def format(localDate: LocalDate): String
|
||||||
|
|
||||||
|
def validatePatternString(): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
class Iso8601DateFormatter(
|
class Iso8601DateFormatter(
|
||||||
|
@ -70,6 +73,12 @@ class Iso8601DateFormatter(
|
||||||
override def format(date: Date): String = {
|
override def format(date: Date): String = {
|
||||||
legacyFormatter.format(date)
|
legacyFormatter.format(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def validatePatternString(): Unit = {
|
||||||
|
try {
|
||||||
|
formatter
|
||||||
|
} catch checkLegacyFormatter(pattern, legacyFormatter.validatePatternString)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait LegacyDateFormatter extends DateFormatter {
|
trait LegacyDateFormatter extends DateFormatter {
|
||||||
|
@ -93,6 +102,7 @@ class LegacyFastDateFormatter(pattern: String, locale: Locale) extends LegacyDat
|
||||||
private lazy val fdf = FastDateFormat.getInstance(pattern, locale)
|
private lazy val fdf = FastDateFormat.getInstance(pattern, locale)
|
||||||
override def parseToDate(s: String): Date = fdf.parse(s)
|
override def parseToDate(s: String): Date = fdf.parse(s)
|
||||||
override def format(d: Date): String = fdf.format(d)
|
override def format(d: Date): String = fdf.format(d)
|
||||||
|
override def validatePatternString(): Unit = fdf
|
||||||
}
|
}
|
||||||
|
|
||||||
class LegacySimpleDateFormatter(pattern: String, locale: Locale) extends LegacyDateFormatter {
|
class LegacySimpleDateFormatter(pattern: String, locale: Locale) extends LegacyDateFormatter {
|
||||||
|
@ -100,6 +110,8 @@ class LegacySimpleDateFormatter(pattern: String, locale: Locale) extends LegacyD
|
||||||
private lazy val sdf = new SimpleDateFormat(pattern, locale)
|
private lazy val sdf = new SimpleDateFormat(pattern, locale)
|
||||||
override def parseToDate(s: String): Date = sdf.parse(s)
|
override def parseToDate(s: String): Date = sdf.parse(s)
|
||||||
override def format(d: Date): String = sdf.format(d)
|
override def format(d: Date): String = sdf.format(d)
|
||||||
|
override def validatePatternString(): Unit = sdf
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object DateFormatter {
|
object DateFormatter {
|
||||||
|
@ -118,7 +130,9 @@ object DateFormatter {
|
||||||
if (SQLConf.get.legacyTimeParserPolicy == LEGACY) {
|
if (SQLConf.get.legacyTimeParserPolicy == LEGACY) {
|
||||||
getLegacyFormatter(pattern, zoneId, locale, legacyFormat)
|
getLegacyFormatter(pattern, zoneId, locale, legacyFormat)
|
||||||
} else {
|
} else {
|
||||||
new Iso8601DateFormatter(pattern, zoneId, locale, legacyFormat)
|
val df = new Iso8601DateFormatter(pattern, zoneId, locale, legacyFormat)
|
||||||
|
df.validatePatternString()
|
||||||
|
df
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,34 @@ trait DateTimeFormatterHelper {
|
||||||
s"set ${SQLConf.LEGACY_TIME_PARSER_POLICY.key} to LEGACY to restore the behavior " +
|
s"set ${SQLConf.LEGACY_TIME_PARSER_POLICY.key} to LEGACY to restore the behavior " +
|
||||||
s"before Spark 3.0, or set to CORRECTED and treat it as an invalid datetime string.", e)
|
s"before Spark 3.0, or set to CORRECTED and treat it as an invalid datetime string.", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the new DateTimeFormatter failed to initialize because of invalid datetime pattern, it
|
||||||
|
* will throw IllegalArgumentException. If the pattern can be recognized by the legacy formatter
|
||||||
|
* it will raise SparkUpgradeException to tell users to restore the previous behavior via LEGACY
|
||||||
|
* policy or follow our guide to correct their pattern. Otherwise, the original
|
||||||
|
* IllegalArgumentException will be thrown.
|
||||||
|
*
|
||||||
|
* @param pattern the date time pattern
|
||||||
|
* @param tryLegacyFormatter a func to capture exception, identically which forces a legacy
|
||||||
|
* datetime formatter to be initialized
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected def checkLegacyFormatter(
|
||||||
|
pattern: String,
|
||||||
|
tryLegacyFormatter: => Unit): PartialFunction[Throwable, DateTimeFormatter] = {
|
||||||
|
case e: IllegalArgumentException =>
|
||||||
|
try {
|
||||||
|
tryLegacyFormatter
|
||||||
|
} catch {
|
||||||
|
case _: Throwable => throw e
|
||||||
|
}
|
||||||
|
throw new SparkUpgradeException("3.0", s"Fail to recognize '$pattern' pattern in the" +
|
||||||
|
s" DateTimeFormatter. 1) You can set ${SQLConf.LEGACY_TIME_PARSER_POLICY.key} to LEGACY" +
|
||||||
|
s" to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern" +
|
||||||
|
s" with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html",
|
||||||
|
e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object DateTimeFormatterHelper {
|
private object DateTimeFormatterHelper {
|
||||||
|
@ -190,6 +218,8 @@ private object DateTimeFormatterHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final val unsupportedLetters = Set('A', 'c', 'e', 'n', 'N', 'p')
|
final val unsupportedLetters = Set('A', 'c', 'e', 'n', 'N', 'p')
|
||||||
|
final val unsupportedNarrowTextStyle =
|
||||||
|
Set("GGGGG", "MMMMM", "LLLLL", "EEEEE", "uuuuu", "QQQQQ", "qqqqq", "uuuuu")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In Spark 3.0, we switch to the Proleptic Gregorian calendar and use DateTimeFormatter for
|
* In Spark 3.0, we switch to the Proleptic Gregorian calendar and use DateTimeFormatter for
|
||||||
|
@ -211,6 +241,9 @@ private object DateTimeFormatterHelper {
|
||||||
for (c <- patternPart if unsupportedLetters.contains(c)) {
|
for (c <- patternPart if unsupportedLetters.contains(c)) {
|
||||||
throw new IllegalArgumentException(s"Illegal pattern character: $c")
|
throw new IllegalArgumentException(s"Illegal pattern character: $c")
|
||||||
}
|
}
|
||||||
|
for (style <- unsupportedNarrowTextStyle if patternPart.contains(style)) {
|
||||||
|
throw new IllegalArgumentException(s"Too many pattern letters: ${style.head}")
|
||||||
|
}
|
||||||
// The meaning of 'u' was day number of week in SimpleDateFormat, it was changed to year
|
// The meaning of 'u' was day number of week in SimpleDateFormat, it was changed to year
|
||||||
// in DateTimeFormatter. Substitute 'u' to 'e' and use DateTimeFormatter to parse the
|
// in DateTimeFormatter. Substitute 'u' to 'e' and use DateTimeFormatter to parse the
|
||||||
// string. If parsable, return the result; otherwise, fall back to 'u', and then use the
|
// string. If parsable, return the result; otherwise, fall back to 'u', and then use the
|
||||||
|
|
|
@ -54,6 +54,7 @@ sealed trait TimestampFormatter extends Serializable {
|
||||||
def format(us: Long): String
|
def format(us: Long): String
|
||||||
def format(ts: Timestamp): String
|
def format(ts: Timestamp): String
|
||||||
def format(instant: Instant): String
|
def format(instant: Instant): String
|
||||||
|
def validatePatternString(): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
class Iso8601TimestampFormatter(
|
class Iso8601TimestampFormatter(
|
||||||
|
@ -99,6 +100,12 @@ class Iso8601TimestampFormatter(
|
||||||
override def format(ts: Timestamp): String = {
|
override def format(ts: Timestamp): String = {
|
||||||
legacyFormatter.format(ts)
|
legacyFormatter.format(ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def validatePatternString(): Unit = {
|
||||||
|
try {
|
||||||
|
formatter
|
||||||
|
} catch checkLegacyFormatter(pattern, legacyFormatter.validatePatternString)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,6 +209,8 @@ class LegacyFastTimestampFormatter(
|
||||||
override def format(instant: Instant): String = {
|
override def format(instant: Instant): String = {
|
||||||
format(instantToMicros(instant))
|
format(instantToMicros(instant))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def validatePatternString(): Unit = fastDateFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
class LegacySimpleTimestampFormatter(
|
class LegacySimpleTimestampFormatter(
|
||||||
|
@ -231,6 +240,8 @@ class LegacySimpleTimestampFormatter(
|
||||||
override def format(instant: Instant): String = {
|
override def format(instant: Instant): String = {
|
||||||
format(instantToMicros(instant))
|
format(instantToMicros(instant))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def validatePatternString(): Unit = sdf
|
||||||
}
|
}
|
||||||
|
|
||||||
object LegacyDateFormats extends Enumeration {
|
object LegacyDateFormats extends Enumeration {
|
||||||
|
@ -255,8 +266,10 @@ object TimestampFormatter {
|
||||||
if (SQLConf.get.legacyTimeParserPolicy == LEGACY) {
|
if (SQLConf.get.legacyTimeParserPolicy == LEGACY) {
|
||||||
getLegacyFormatter(pattern, zoneId, locale, legacyFormat)
|
getLegacyFormatter(pattern, zoneId, locale, legacyFormat)
|
||||||
} else {
|
} else {
|
||||||
new Iso8601TimestampFormatter(
|
val tf = new Iso8601TimestampFormatter(
|
||||||
pattern, zoneId, locale, legacyFormat, needVarLengthSecondFraction)
|
pattern, zoneId, locale, legacyFormat, needVarLengthSecondFraction)
|
||||||
|
tf.validatePatternString()
|
||||||
|
tf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
|
||||||
|
|
||||||
// Test escaping of format
|
// Test escaping of format
|
||||||
GenerateUnsafeProjection.generate(
|
GenerateUnsafeProjection.generate(
|
||||||
DateFormatClass(Literal(ts), Literal("\"quote"), JST_OPT) :: Nil)
|
DateFormatClass(Literal(ts), Literal("\""), JST_OPT) :: Nil)
|
||||||
|
|
||||||
// SPARK-28072 The codegen path should work
|
// SPARK-28072 The codegen path should work
|
||||||
checkEvaluation(
|
checkEvaluation(
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package org.apache.spark.sql.catalyst.util
|
package org.apache.spark.sql.catalyst.util
|
||||||
|
|
||||||
import org.apache.spark.SparkFunSuite
|
import org.apache.spark.{SparkFunSuite, SparkUpgradeException}
|
||||||
import org.apache.spark.sql.catalyst.util.DateTimeFormatterHelper._
|
import org.apache.spark.sql.catalyst.util.DateTimeFormatterHelper._
|
||||||
|
|
||||||
class DateTimeFormatterHelperSuite extends SparkFunSuite {
|
class DateTimeFormatterHelperSuite extends SparkFunSuite {
|
||||||
|
@ -40,6 +40,16 @@ class DateTimeFormatterHelperSuite extends SparkFunSuite {
|
||||||
val e = intercept[IllegalArgumentException](convertIncompatiblePattern(s"yyyy-MM-dd $l G"))
|
val e = intercept[IllegalArgumentException](convertIncompatiblePattern(s"yyyy-MM-dd $l G"))
|
||||||
assert(e.getMessage === s"Illegal pattern character: $l")
|
assert(e.getMessage === s"Illegal pattern character: $l")
|
||||||
}
|
}
|
||||||
|
unsupportedNarrowTextStyle.foreach { style =>
|
||||||
|
val e1 = intercept[IllegalArgumentException] {
|
||||||
|
convertIncompatiblePattern(s"yyyy-MM-dd $style")
|
||||||
|
}
|
||||||
|
assert(e1.getMessage === s"Too many pattern letters: ${style.head}")
|
||||||
|
val e2 = intercept[IllegalArgumentException] {
|
||||||
|
convertIncompatiblePattern(s"yyyy-MM-dd $style${style.head}")
|
||||||
|
}
|
||||||
|
assert(e2.getMessage === s"Too many pattern letters: ${style.head}")
|
||||||
|
}
|
||||||
assert(convertIncompatiblePattern("yyyy-MM-dd uuuu") === "uuuu-MM-dd eeee")
|
assert(convertIncompatiblePattern("yyyy-MM-dd uuuu") === "uuuu-MM-dd eeee")
|
||||||
assert(convertIncompatiblePattern("yyyy-MM-dd EEEE") === "uuuu-MM-dd EEEE")
|
assert(convertIncompatiblePattern("yyyy-MM-dd EEEE") === "uuuu-MM-dd EEEE")
|
||||||
assert(convertIncompatiblePattern("yyyy-MM-dd'e'HH:mm:ss") === "uuuu-MM-dd'e'HH:mm:ss")
|
assert(convertIncompatiblePattern("yyyy-MM-dd'e'HH:mm:ss") === "uuuu-MM-dd'e'HH:mm:ss")
|
||||||
|
|
|
@ -396,4 +396,15 @@ class TimestampFormatterSuite extends SparkFunSuite with SQLHelper with Matchers
|
||||||
val micros = formatter.parse("2009 11")
|
val micros = formatter.parse("2009 11")
|
||||||
assert(micros === date(2009, 1, 1, 11))
|
assert(micros === date(2009, 1, 1, 11))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("explicitly forbidden datetime patterns") {
|
||||||
|
// not support by the legacy one too
|
||||||
|
Seq("QQQQQ", "qqqqq", "A", "c", "e", "n", "N", "p").foreach { pattern =>
|
||||||
|
intercept[IllegalArgumentException](TimestampFormatter(pattern, UTC).format(0))
|
||||||
|
}
|
||||||
|
// supported by the legacy one, then we will suggest users with SparkUpgradeException
|
||||||
|
Seq("GGGGG", "MMMMM", "LLLLL", "EEEEE", "uuuuu", "aa", "aaa").foreach { pattern =>
|
||||||
|
intercept[SparkUpgradeException](TimestampFormatter(pattern, UTC).format(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
--SET spark.sql.legacy.timeParserPolicy=LEGACY
|
||||||
|
--IMPORT datetime.sql
|
|
@ -140,3 +140,23 @@ select to_date("16", "dd");
|
||||||
select to_date("02-29", "MM-dd");
|
select to_date("02-29", "MM-dd");
|
||||||
select to_timestamp("2019 40", "yyyy mm");
|
select to_timestamp("2019 40", "yyyy mm");
|
||||||
select to_timestamp("2019 10:10:10", "yyyy hh:mm:ss");
|
select to_timestamp("2019 10:10:10", "yyyy hh:mm:ss");
|
||||||
|
|
||||||
|
-- Unsupported narrow text style
|
||||||
|
select date_format(date '2020-05-23', 'GGGGG');
|
||||||
|
select date_format(date '2020-05-23', 'MMMMM');
|
||||||
|
select date_format(date '2020-05-23', 'LLLLL');
|
||||||
|
select date_format(timestamp '2020-05-23', 'EEEEE');
|
||||||
|
select date_format(timestamp '2020-05-23', 'uuuuu');
|
||||||
|
select date_format('2020-05-23', 'QQQQQ');
|
||||||
|
select date_format('2020-05-23', 'qqqqq');
|
||||||
|
select to_timestamp('2019-10-06 A', 'yyyy-MM-dd GGGGG');
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEEE');
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE');
|
||||||
|
select unix_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE');
|
||||||
|
select from_unixtime(12345, 'MMMMM');
|
||||||
|
select from_unixtime(54321, 'QQQQQ');
|
||||||
|
select from_unixtime(23456, 'aaaaa');
|
||||||
|
select from_json('{"time":"26/October/2015"}', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'));
|
||||||
|
select from_json('{"date":"26/October/2015"}', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'));
|
||||||
|
select from_csv('26/October/2015', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'));
|
||||||
|
select from_csv('26/October/2015', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- Automatically generated by SQLQueryTestSuite
|
-- Automatically generated by SQLQueryTestSuite
|
||||||
-- Number of queries: 92
|
-- Number of queries: 116
|
||||||
|
|
||||||
|
|
||||||
-- !query
|
-- !query
|
||||||
|
@ -838,3 +838,164 @@ select to_timestamp("2019 10:10:10", "yyyy hh:mm:ss")
|
||||||
struct<to_timestamp(2019 10:10:10, yyyy hh:mm:ss):timestamp>
|
struct<to_timestamp(2019 10:10:10, yyyy hh:mm:ss):timestamp>
|
||||||
-- !query output
|
-- !query output
|
||||||
2019-01-01 10:10:10
|
2019-01-01 10:10:10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'GGGGG' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'MMMMM' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'LLLLL')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'LLLLL' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'uuuuu')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'uuuuu' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Too many pattern letters: Q
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'qqqqq')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Too many pattern letters: q
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 A', 'yyyy-MM-dd GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'yyyy-MM-dd GGGGG' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select unix_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(12345, 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'MMMMM' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(54321, 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<from_unixtime(CAST(54321 AS BIGINT), QQQQQ):string>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(23456, 'aaaaa')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'aaaaa' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"time":"26/October/2015"}', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"date":"26/October/2015"}', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
|
@ -0,0 +1,958 @@
|
||||||
|
-- Automatically generated by SQLQueryTestSuite
|
||||||
|
-- Number of queries: 116
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_SECONDS(1230219000),TIMESTAMP_SECONDS(-1230219000),TIMESTAMP_SECONDS(null)
|
||||||
|
-- !query schema
|
||||||
|
struct<timestamp_seconds(1230219000):timestamp,timestamp_seconds(-1230219000):timestamp,timestamp_seconds(CAST(NULL AS INT)):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2008-12-25 07:30:00 1931-01-07 00:30:00 NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_MILLIS(1230219000123),TIMESTAMP_MILLIS(-1230219000123),TIMESTAMP_MILLIS(null)
|
||||||
|
-- !query schema
|
||||||
|
struct<timestamp_millis(1230219000123):timestamp,timestamp_millis(-1230219000123):timestamp,timestamp_millis(CAST(NULL AS INT)):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2008-12-25 07:30:00.123 1931-01-07 00:29:59.877 NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_MICROS(1230219000123123),TIMESTAMP_MICROS(-1230219000123123),TIMESTAMP_MICROS(null)
|
||||||
|
-- !query schema
|
||||||
|
struct<timestamp_micros(1230219000123123):timestamp,timestamp_micros(-1230219000123123):timestamp,timestamp_micros(CAST(NULL AS INT)):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2008-12-25 07:30:00.123123 1931-01-07 00:29:59.876877 NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_SECONDS(1230219000123123)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.ArithmeticException
|
||||||
|
long overflow
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_SECONDS(-1230219000123123)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.ArithmeticException
|
||||||
|
long overflow
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_MILLIS(92233720368547758)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.ArithmeticException
|
||||||
|
long overflow
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select TIMESTAMP_MILLIS(-92233720368547758)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.ArithmeticException
|
||||||
|
long overflow
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select current_date = current_date(), current_timestamp = current_timestamp()
|
||||||
|
-- !query schema
|
||||||
|
struct<(current_date() = current_date()):boolean,(current_timestamp() = current_timestamp()):boolean>
|
||||||
|
-- !query output
|
||||||
|
true true
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_date(null), to_date('2016-12-31'), to_date('2016-12-31', 'yyyy-MM-dd')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_date(NULL):date,to_date(2016-12-31):date,to_date(2016-12-31, yyyy-MM-dd):date>
|
||||||
|
-- !query output
|
||||||
|
NULL 2016-12-31 2016-12-31
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp(null), to_timestamp('2016-12-31 00:12:00'), to_timestamp('2016-12-31', 'yyyy-MM-dd')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(NULL):timestamp,to_timestamp(2016-12-31 00:12:00):timestamp,to_timestamp(2016-12-31, yyyy-MM-dd):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL 2016-12-31 00:12:00 2016-12-31 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select dayofweek('2007-02-03'), dayofweek('2009-07-30'), dayofweek('2017-05-27'), dayofweek(null), dayofweek('1582-10-15 13:10:15')
|
||||||
|
-- !query schema
|
||||||
|
struct<dayofweek(CAST(2007-02-03 AS DATE)):int,dayofweek(CAST(2009-07-30 AS DATE)):int,dayofweek(CAST(2017-05-27 AS DATE)):int,dayofweek(CAST(NULL AS DATE)):int,dayofweek(CAST(1582-10-15 13:10:15 AS DATE)):int>
|
||||||
|
-- !query output
|
||||||
|
7 5 7 NULL 6
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
create temporary view ttf1 as select * from values
|
||||||
|
(1, 2),
|
||||||
|
(2, 3)
|
||||||
|
as ttf1(current_date, current_timestamp)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select current_date, current_timestamp from ttf1
|
||||||
|
-- !query schema
|
||||||
|
struct<current_date:int,current_timestamp:int>
|
||||||
|
-- !query output
|
||||||
|
1 2
|
||||||
|
2 3
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
create temporary view ttf2 as select * from values
|
||||||
|
(1, 2),
|
||||||
|
(2, 3)
|
||||||
|
as ttf2(a, b)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select current_date = current_date(), current_timestamp = current_timestamp(), a, b from ttf2
|
||||||
|
-- !query schema
|
||||||
|
struct<(current_date() = current_date()):boolean,(current_timestamp() = current_timestamp()):boolean,a:int,b:int>
|
||||||
|
-- !query output
|
||||||
|
true true 1 2
|
||||||
|
true true 2 3
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select a, b from ttf2 order by a, current_date
|
||||||
|
-- !query schema
|
||||||
|
struct<a:int,b:int>
|
||||||
|
-- !query output
|
||||||
|
1 2
|
||||||
|
2 3
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select weekday('2007-02-03'), weekday('2009-07-30'), weekday('2017-05-27'), weekday(null), weekday('1582-10-15 13:10:15')
|
||||||
|
-- !query schema
|
||||||
|
struct<weekday(CAST(2007-02-03 AS DATE)):int,weekday(CAST(2009-07-30 AS DATE)):int,weekday(CAST(2017-05-27 AS DATE)):int,weekday(CAST(NULL AS DATE)):int,weekday(CAST(1582-10-15 13:10:15 AS DATE)):int>
|
||||||
|
-- !query output
|
||||||
|
5 3 5 NULL 4
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select year('1500-01-01'), month('1500-01-01'), dayOfYear('1500-01-01')
|
||||||
|
-- !query schema
|
||||||
|
struct<year(CAST(1500-01-01 AS DATE)):int,month(CAST(1500-01-01 AS DATE)):int,dayofyear(CAST(1500-01-01 AS DATE)):int>
|
||||||
|
-- !query output
|
||||||
|
1500 1 1
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2019-01-01\t'
|
||||||
|
-- !query schema
|
||||||
|
struct<DATE '2019-01-01':date>
|
||||||
|
-- !query output
|
||||||
|
2019-01-01
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select timestamp '2019-01-01\t'
|
||||||
|
-- !query schema
|
||||||
|
struct<TIMESTAMP '2019-01-01 00:00:00':timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-01-01 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select timestamp'2011-11-11 11:11:11' + interval '2' day
|
||||||
|
-- !query schema
|
||||||
|
struct<CAST(TIMESTAMP '2011-11-11 11:11:11' + INTERVAL '2 days' AS TIMESTAMP):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2011-11-13 11:11:11
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select timestamp'2011-11-11 11:11:11' - interval '2' day
|
||||||
|
-- !query schema
|
||||||
|
struct<CAST(TIMESTAMP '2011-11-11 11:11:11' - INTERVAL '2 days' AS TIMESTAMP):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2011-11-09 11:11:11
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date'2011-11-11 11:11:11' + interval '2' second
|
||||||
|
-- !query schema
|
||||||
|
struct<DATE '2011-11-11' + INTERVAL '2 seconds':date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-11
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date'2011-11-11 11:11:11' - interval '2' second
|
||||||
|
-- !query schema
|
||||||
|
struct<DATE '2011-11-11' - INTERVAL '2 seconds':date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select '2011-11-11' - interval '2' day
|
||||||
|
-- !query schema
|
||||||
|
struct<CAST(2011-11-11 - INTERVAL '2 days' AS STRING):string>
|
||||||
|
-- !query output
|
||||||
|
2011-11-09 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select '2011-11-11 11:11:11' - interval '2' second
|
||||||
|
-- !query schema
|
||||||
|
struct<CAST(2011-11-11 11:11:11 - INTERVAL '2 seconds' AS STRING):string>
|
||||||
|
-- !query output
|
||||||
|
2011-11-11 11:11:09
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select '1' - interval '2' second
|
||||||
|
-- !query schema
|
||||||
|
struct<CAST(1 - INTERVAL '2 seconds' AS STRING):string>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select 1 - interval '2' second
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve '1 + (- INTERVAL '2 seconds')' due to data type mismatch: argument 1 requires timestamp type, however, '1' is of int type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date'2020-01-01' - timestamp'2019-10-06 10:11:12.345678'
|
||||||
|
-- !query schema
|
||||||
|
struct<subtracttimestamps(CAST(DATE '2020-01-01' AS TIMESTAMP), TIMESTAMP '2019-10-06 10:11:12.345678'):interval>
|
||||||
|
-- !query output
|
||||||
|
2078 hours 48 minutes 47.654322 seconds
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select timestamp'2019-10-06 10:11:12.345678' - date'2020-01-01'
|
||||||
|
-- !query schema
|
||||||
|
struct<subtracttimestamps(TIMESTAMP '2019-10-06 10:11:12.345678', CAST(DATE '2020-01-01' AS TIMESTAMP)):interval>
|
||||||
|
-- !query output
|
||||||
|
-2078 hours -48 minutes -47.654322 seconds
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select timestamp'2019-10-06 10:11:12.345678' - null
|
||||||
|
-- !query schema
|
||||||
|
struct<subtracttimestamps(TIMESTAMP '2019-10-06 10:11:12.345678', CAST(NULL AS TIMESTAMP)):interval>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select null - timestamp'2019-10-06 10:11:12.345678'
|
||||||
|
-- !query schema
|
||||||
|
struct<subtracttimestamps(CAST(NULL AS TIMESTAMP), TIMESTAMP '2019-10-06 10:11:12.345678'):interval>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1Y)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(CAST(2011-11-11 AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1S)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(CAST(2011-11-11 AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(CAST(2011-11-11 AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1L)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(CAST('2011-11-11' AS DATE), 1L)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, '1L' is of bigint type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1.0)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(CAST('2011-11-11' AS DATE), 1.0BD)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, '1.0BD' is of decimal(2,1) type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', 1E1)
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(CAST('2011-11-11' AS DATE), 10.0D)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, '10.0D' is of double type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', '1')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(CAST(2011-11-11 AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', '1.2')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
The second argument of 'date_add' function needs to be an integer.;
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add(date'2011-11-11', 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(DATE '2011-11-11', 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add(timestamp'2011-11-11', 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(CAST(TIMESTAMP '2011-11-11 00:00:00' AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(date'2011-11-11', 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(DATE '2011-11-11', 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(date'2011-11-11', '1')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(DATE '2011-11-11', 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(date'2011-11-11', '1.2')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
The second argument of 'date_sub' function needs to be an integer.;
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(timestamp'2011-11-11', 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(CAST(TIMESTAMP '2011-11-11 00:00:00' AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
2011-11-10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(null, 1)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(CAST(NULL AS DATE), 1):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub(date'2011-11-11', null)
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(DATE '2011-11-11', CAST(NULL AS INT)):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date'2011-11-11' + 1E1
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(DATE '2011-11-11', 10.0D)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, '10.0D' is of double type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date'2011-11-11' + '1'
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(DATE '2011-11-11', CAST('1' AS DOUBLE))' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, 'CAST('1' AS DOUBLE)' is of double type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select null + date '2001-09-28'
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(DATE '2001-09-28', CAST(NULL AS INT)):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-09-28' + 7Y
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(DATE '2001-09-28', 7):date>
|
||||||
|
-- !query output
|
||||||
|
2001-10-05
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select 7S + date '2001-09-28'
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(DATE '2001-09-28', 7):date>
|
||||||
|
-- !query output
|
||||||
|
2001-10-05
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-10-01' - 7
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(DATE '2001-10-01', 7):date>
|
||||||
|
-- !query output
|
||||||
|
2001-09-24
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-10-01' - '7'
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_sub(DATE '2001-10-01', CAST('7' AS DOUBLE))' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, 'CAST('7' AS DOUBLE)' is of double type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-09-28' + null
|
||||||
|
-- !query schema
|
||||||
|
struct<date_add(DATE '2001-09-28', CAST(NULL AS INT)):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-09-28' - null
|
||||||
|
-- !query schema
|
||||||
|
struct<date_sub(DATE '2001-09-28', CAST(NULL AS INT)):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
create temp view v as select '1' str
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_add('2011-11-11', str) from v
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_add(CAST('2011-11-11' AS DATE), v.`str`)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, 'v.`str`' is of string type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_sub('2011-11-11', str) from v
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.sql.AnalysisException
|
||||||
|
cannot resolve 'date_sub(CAST('2011-11-11' AS DATE), v.`str`)' due to data type mismatch: argument 2 requires (int or smallint or tinyint) type, however, 'v.`str`' is of string type.; line 1 pos 7
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select null - date '2019-10-06'
|
||||||
|
-- !query schema
|
||||||
|
struct<subtractdates(CAST(NULL AS DATE), DATE '2019-10-06'):interval>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date '2001-10-01' - date '2001-09-28'
|
||||||
|
-- !query schema
|
||||||
|
struct<subtractdates(DATE '2001-10-01', DATE '2001-09-28'):interval>
|
||||||
|
-- !query output
|
||||||
|
3 days
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12., yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.0', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.0, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.1', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.1, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.12', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.12, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.123UTC', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.123UTC, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.1234', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.1234, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.12345CST', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.12345CST, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.123456PST', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.123456PST, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.1234567PST', 'yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.1234567PST, yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('123456 2019-10-06 10:11:12.123456PST', 'SSSSSS yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(123456 2019-10-06 10:11:12.123456PST, SSSSSS yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('223456 2019-10-06 10:11:12.123456PST', 'SSSSSS yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(223456 2019-10-06 10:11:12.123456PST, SSSSSS yyyy-MM-dd HH:mm:ss.SSSSSS[zzz]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.1234', 'yyyy-MM-dd HH:mm:ss.[SSSSSS]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.1234, yyyy-MM-dd HH:mm:ss.[SSSSSS]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.123', 'yyyy-MM-dd HH:mm:ss[.SSSSSS]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.123, yyyy-MM-dd HH:mm:ss[.SSSSSS]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12', 'yyyy-MM-dd HH:mm:ss[.SSSSSS]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12, yyyy-MM-dd HH:mm:ss[.SSSSSS]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11:12.12', 'yyyy-MM-dd HH:mm[:ss.SSSSSS]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11:12.12, yyyy-MM-dd HH:mm[:ss.SSSSSS]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 10:11', 'yyyy-MM-dd HH:mm[:ss.SSSSSS]')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 10:11, yyyy-MM-dd HH:mm[:ss.SSSSSS]):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019-10-06S10:11:12.12345", "yyyy-MM-dd'S'HH:mm:ss.SSSSSS")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06S10:11:12.12345, yyyy-MM-dd'S'HH:mm:ss.SSSSSS):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("12.12342019-10-06S10:11", "ss.SSSSyyyy-MM-dd'S'HH:mm")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(12.12342019-10-06S10:11, ss.SSSSyyyy-MM-dd'S'HH:mm):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("12.1232019-10-06S10:11", "ss.SSSSyyyy-MM-dd'S'HH:mm")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(12.1232019-10-06S10:11, ss.SSSSyyyy-MM-dd'S'HH:mm):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("12.1232019-10-06S10:11", "ss.SSSSyy-MM-dd'S'HH:mm")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(12.1232019-10-06S10:11, ss.SSSSyy-MM-dd'S'HH:mm):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("12.1234019-10-06S10:11", "ss.SSSSy-MM-dd'S'HH:mm")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(12.1234019-10-06S10:11, ss.SSSSy-MM-dd'S'HH:mm):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019-10-06S", "yyyy-MM-dd'S'")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06S, yyyy-MM-dd'S'):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("S2019-10-06", "'S'yyyy-MM-dd")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(S2019-10-06, 'S'yyyy-MM-dd):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2019-10-06', 'yyyy-MM-dd uuee')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Illegal pattern character 'e'
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2019-10-06', 'yyyy-MM-dd uucc')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Illegal pattern character 'c'
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2019-10-06', 'yyyy-MM-dd uuuu')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(TIMESTAMP '2019-10-06 00:00:00', yyyy-MM-dd uuuu):string>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 0007
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019-10-06T10:11:12'12", "yyyy-MM-dd'T'HH:mm:ss''SSSS")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06T10:11:12'12, yyyy-MM-dd'T'HH:mm:ss''SSSS):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 10:11:12.012
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019-10-06T10:11:12'", "yyyy-MM-dd'T'HH:mm:ss''")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06T10:11:12', yyyy-MM-dd'T'HH:mm:ss''):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 10:11:12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("'2019-10-06T10:11:12", "''yyyy-MM-dd'T'HH:mm:ss")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp('2019-10-06T10:11:12, ''yyyy-MM-dd'T'HH:mm:ss):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 10:11:12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("P2019-10-06T10:11:12", "'P'yyyy-MM-dd'T'HH:mm:ss")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(P2019-10-06T10:11:12, 'P'yyyy-MM-dd'T'HH:mm:ss):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-10-06 10:11:12
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("16", "dd")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(16, dd):timestamp>
|
||||||
|
-- !query output
|
||||||
|
1970-01-16 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("02-29", "MM-dd")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(02-29, MM-dd):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_date("16", "dd")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_date(16, dd):date>
|
||||||
|
-- !query output
|
||||||
|
1970-01-16
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_date("02-29", "MM-dd")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_date(02-29, MM-dd):date>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019 40", "yyyy mm")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019 40, yyyy mm):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-01-01 00:40:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp("2019 10:10:10", "yyyy hh:mm:ss")
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019 10:10:10, yyyy hh:mm:ss):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2019-01-01 10:10:10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(CAST(DATE '2020-05-23' AS TIMESTAMP), GGGGG):string>
|
||||||
|
-- !query output
|
||||||
|
AD
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(CAST(DATE '2020-05-23' AS TIMESTAMP), MMMMM):string>
|
||||||
|
-- !query output
|
||||||
|
May
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'LLLLL')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(CAST(DATE '2020-05-23' AS TIMESTAMP), LLLLL):string>
|
||||||
|
-- !query output
|
||||||
|
May
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(TIMESTAMP '2020-05-23 00:00:00', EEEEE):string>
|
||||||
|
-- !query output
|
||||||
|
Saturday
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'uuuuu')
|
||||||
|
-- !query schema
|
||||||
|
struct<date_format(TIMESTAMP '2020-05-23 00:00:00', uuuuu):string>
|
||||||
|
-- !query output
|
||||||
|
00006
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Illegal pattern character 'Q'
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'qqqqq')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Illegal pattern character 'q'
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 A', 'yyyy-MM-dd GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(2019-10-06 A, yyyy-MM-dd GGGGG):timestamp>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(22 05 2020 Friday, dd MM yyyy EEEEEE):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2020-05-22 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<to_timestamp(22 05 2020 Friday, dd MM yyyy EEEEE):timestamp>
|
||||||
|
-- !query output
|
||||||
|
2020-05-22 00:00:00
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select unix_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<unix_timestamp(22 05 2020 Friday, dd MM yyyy EEEEE):bigint>
|
||||||
|
-- !query output
|
||||||
|
1590130800
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(12345, 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<from_unixtime(CAST(12345 AS BIGINT), MMMMM):string>
|
||||||
|
-- !query output
|
||||||
|
December
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(54321, 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<from_unixtime(CAST(54321 AS BIGINT), QQQQQ):string>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(23456, 'aaaaa')
|
||||||
|
-- !query schema
|
||||||
|
struct<from_unixtime(CAST(23456 AS BIGINT), aaaaa):string>
|
||||||
|
-- !query output
|
||||||
|
PM
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"time":"26/October/2015"}', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<from_json({"time":"26/October/2015"}):struct<time:timestamp>>
|
||||||
|
-- !query output
|
||||||
|
{"time":2015-10-26 00:00:00}
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"date":"26/October/2015"}', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<from_json({"date":"26/October/2015"}):struct<date:date>>
|
||||||
|
-- !query output
|
||||||
|
{"date":2015-10-26}
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<from_csv(26/October/2015):struct<time:timestamp>>
|
||||||
|
-- !query output
|
||||||
|
{"time":2015-10-26 00:00:00}
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<from_csv(26/October/2015):struct<date:date>>
|
||||||
|
-- !query output
|
||||||
|
{"date":2015-10-26}
|
|
@ -1,5 +1,5 @@
|
||||||
-- Automatically generated by SQLQueryTestSuite
|
-- Automatically generated by SQLQueryTestSuite
|
||||||
-- Number of queries: 91
|
-- Number of queries: 116
|
||||||
|
|
||||||
|
|
||||||
-- !query
|
-- !query
|
||||||
|
@ -810,3 +810,164 @@ select to_timestamp("2019 10:10:10", "yyyy hh:mm:ss")
|
||||||
struct<to_timestamp(2019 10:10:10, yyyy hh:mm:ss):timestamp>
|
struct<to_timestamp(2019 10:10:10, yyyy hh:mm:ss):timestamp>
|
||||||
-- !query output
|
-- !query output
|
||||||
2019-01-01 10:10:10
|
2019-01-01 10:10:10
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'GGGGG' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'MMMMM' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(date '2020-05-23', 'LLLLL')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'LLLLL' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format(timestamp '2020-05-23', 'uuuuu')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'uuuuu' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Too many pattern letters: Q
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select date_format('2020-05-23', 'qqqqq')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
Too many pattern letters: q
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('2019-10-06 A', 'yyyy-MM-dd GGGGG')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'yyyy-MM-dd GGGGG' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select to_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select unix_timestamp('22 05 2020 Friday', 'dd MM yyyy EEEEE')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd MM yyyy EEEEE' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(12345, 'MMMMM')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'MMMMM' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(54321, 'QQQQQ')
|
||||||
|
-- !query schema
|
||||||
|
struct<from_unixtime(CAST(54321 AS BIGINT), QQQQQ):string>
|
||||||
|
-- !query output
|
||||||
|
NULL
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_unixtime(23456, 'aaaaa')
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'aaaaa' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"time":"26/October/2015"}', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_json('{"date":"26/October/2015"}', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'time Timestamp', map('timestampFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
|
-- !query
|
||||||
|
select from_csv('26/October/2015', 'date Date', map('dateFormat', 'dd/MMMMM/yyyy'))
|
||||||
|
-- !query schema
|
||||||
|
struct<>
|
||||||
|
-- !query output
|
||||||
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'dd/MMMMM/yyyy' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
|
@ -136,9 +136,10 @@ NULL
|
||||||
-- !query
|
-- !query
|
||||||
select to_timestamp('2018-01-01', a) from t
|
select to_timestamp('2018-01-01', a) from t
|
||||||
-- !query schema
|
-- !query schema
|
||||||
struct<to_timestamp(2018-01-01, a):timestamp>
|
struct<>
|
||||||
-- !query output
|
-- !query output
|
||||||
NULL
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'aa' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
-- !query
|
-- !query
|
||||||
|
@ -152,9 +153,10 @@ NULL
|
||||||
-- !query
|
-- !query
|
||||||
select to_unix_timestamp('2018-01-01', a) from t
|
select to_unix_timestamp('2018-01-01', a) from t
|
||||||
-- !query schema
|
-- !query schema
|
||||||
struct<to_unix_timestamp(2018-01-01, a):bigint>
|
struct<>
|
||||||
-- !query output
|
-- !query output
|
||||||
NULL
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'aa' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
-- !query
|
-- !query
|
||||||
|
@ -168,9 +170,10 @@ NULL
|
||||||
-- !query
|
-- !query
|
||||||
select unix_timestamp('2018-01-01', a) from t
|
select unix_timestamp('2018-01-01', a) from t
|
||||||
-- !query schema
|
-- !query schema
|
||||||
struct<unix_timestamp(2018-01-01, a):bigint>
|
struct<>
|
||||||
-- !query output
|
-- !query output
|
||||||
NULL
|
org.apache.spark.SparkUpgradeException
|
||||||
|
You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'aa' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
|
||||||
|
|
||||||
|
|
||||||
-- !query
|
-- !query
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.time.{Instant, LocalDateTime, ZoneId}
|
||||||
import java.util.{Locale, TimeZone}
|
import java.util.{Locale, TimeZone}
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
import org.apache.spark.SparkException
|
import org.apache.spark.{SparkException, SparkUpgradeException}
|
||||||
import org.apache.spark.sql.catalyst.util.DateTimeTestUtils.{CEST, LA}
|
import org.apache.spark.sql.catalyst.util.DateTimeTestUtils.{CEST, LA}
|
||||||
import org.apache.spark.sql.catalyst.util.DateTimeUtils
|
import org.apache.spark.sql.catalyst.util.DateTimeUtils
|
||||||
import org.apache.spark.sql.functions._
|
import org.apache.spark.sql.functions._
|
||||||
|
@ -450,9 +450,9 @@ class DateFunctionsSuite extends QueryTest with SharedSparkSession {
|
||||||
checkAnswer(
|
checkAnswer(
|
||||||
df.select(to_date(col("s"), "yyyy-hh-MM")),
|
df.select(to_date(col("s"), "yyyy-hh-MM")),
|
||||||
Seq(Row(null), Row(null), Row(null)))
|
Seq(Row(null), Row(null), Row(null)))
|
||||||
checkAnswer(
|
val e = intercept[SparkUpgradeException](df.select(to_date(col("s"), "yyyy-dd-aa")).collect())
|
||||||
df.select(to_date(col("s"), "yyyy-dd-aa")),
|
assert(e.getCause.isInstanceOf[IllegalArgumentException])
|
||||||
Seq(Row(null), Row(null), Row(null)))
|
assert(e.getMessage.contains("You may get a different result due to the upgrading of Spark"))
|
||||||
|
|
||||||
// february
|
// february
|
||||||
val x1 = "2016-02-29"
|
val x1 = "2016-02-29"
|
||||||
|
@ -618,8 +618,16 @@ class DateFunctionsSuite extends QueryTest with SharedSparkSession {
|
||||||
Row(secs(ts4.getTime)), Row(null), Row(secs(ts3.getTime)), Row(null)))
|
Row(secs(ts4.getTime)), Row(null), Row(secs(ts3.getTime)), Row(null)))
|
||||||
|
|
||||||
// invalid format
|
// invalid format
|
||||||
checkAnswer(df1.selectExpr(s"unix_timestamp(x, 'yyyy-MM-dd aa:HH:ss')"), Seq(
|
val invalid = df1.selectExpr(s"unix_timestamp(x, 'yyyy-MM-dd aa:HH:ss')")
|
||||||
Row(null), Row(null), Row(null), Row(null)))
|
if (legacyParserPolicy == "legacy") {
|
||||||
|
checkAnswer(invalid,
|
||||||
|
Seq(Row(null), Row(null), Row(null), Row(null)))
|
||||||
|
} else {
|
||||||
|
val e = intercept[SparkUpgradeException](invalid.collect())
|
||||||
|
assert(e.getCause.isInstanceOf[IllegalArgumentException])
|
||||||
|
assert(
|
||||||
|
e.getMessage.contains("You may get a different result due to the upgrading of Spark"))
|
||||||
|
}
|
||||||
|
|
||||||
// february
|
// february
|
||||||
val y1 = "2016-02-29"
|
val y1 = "2016-02-29"
|
||||||
|
|
Loading…
Reference in a new issue