From 3789eb17f1acbc8f696e8e2e2e6a1d4fc9f8ba12 Mon Sep 17 00:00:00 2001 From: Maxim Gekk Date: Fri, 6 Sep 2019 23:36:00 +0900 Subject: [PATCH] [SPARK-28690][SQL] Add `date_part` function for timestamps/dates ## What changes were proposed in this pull request? In the PR, I propose new function `date_part()`. The function is modeled on the traditional Ingres equivalent to the SQL-standard function `extract`: ``` date_part('field', source) ``` and added for feature parity with PostgreSQL (https://www.postgresql.org/docs/11/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT). The `source` can have `DATE` or `TIMESTAMP` type. Supported string values of `'field'` are: - `millennium` - the current millennium for given date (or a timestamp implicitly casted to a date). For example, years in the 1900s are in the second millennium. The third millennium started _January 1, 2001_. - `century` - the current millennium for given date (or timestamp). The first century starts at 0001-01-01 AD. - `decade` - the current decade for given date (or timestamp). Actually, this is the year field divided by 10. - isoyear` - the ISO 8601 week-numbering year that the date falls in. Each ISO 8601 week-numbering year begins with the Monday of the week containing the 4th of January. - `year`, `month`, `day`, `hour`, `minute`, `second` - `week` - the number of the ISO 8601 week-numbering week of the year. By definition, ISO weeks start on Mondays and the first week of a year contains January 4 of that year. - `quarter` - the quarter of the year (1 - 4) - `dayofweek` - the day of the week for date/timestamp (1 = Sunday, 2 = Monday, ..., 7 = Saturday) - `dow` - the day of the week as Sunday (0) to Saturday (6) - `isodow` - the day of the week as Monday (1) to Sunday (7) - `doy` - the day of the year (1 - 365/366) - `milliseconds` - the seconds field including fractional parts multiplied by 1,000. - `microseconds` - the seconds field including fractional parts multiplied by 1,000,000. - `epoch` - the number of seconds since 1970-01-01 00:00:00 local time in microsecond precision. Here are examples: ```sql spark-sql> select date_part('year', timestamp'2019-08-12 01:00:00.123456'); 2019 spark-sql> select date_part('week', timestamp'2019-08-12 01:00:00.123456'); 33 spark-sql> select date_part('doy', timestamp'2019-08-12 01:00:00.123456'); 224 ``` I changed implementation of `extract` to re-use `date_part()` internally. ## How was this patch tested? Added `date_part.sql` and regenerated results of `extract.sql`. Closes #25410 from MaxGekk/date_part. Lead-authored-by: Maxim Gekk Co-authored-by: Takeshi Yamamuro Signed-off-by: Takeshi Yamamuro --- .../catalyst/analysis/FunctionRegistry.scala | 1 + .../expressions/datetimeExpressions.scala | 87 ++++ .../sql/catalyst/parser/AstBuilder.scala | 48 +- .../resources/sql-tests/inputs/date_part.sql | 68 +++ .../sql-tests/inputs/pgSQL/timestamp.sql | 31 +- .../sql-tests/results/date_part.sql.out | 412 ++++++++++++++++++ .../sql-tests/results/extract.sql.out | 126 +++--- .../sql-tests/results/pgSQL/date.sql.out | 52 +-- .../sql-tests/results/pgSQL/timestamp.sql.out | 55 ++- 9 files changed, 727 insertions(+), 153 deletions(-) create mode 100644 sql/core/src/test/resources/sql-tests/inputs/date_part.sql create mode 100644 sql/core/src/test/resources/sql-tests/results/date_part.sql.out diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala index 5177f1e55829e..d5728b9027579 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala @@ -417,6 +417,7 @@ object FunctionRegistry { expression[TimeWindow]("window"), expression[MakeDate]("make_date"), expression[MakeTimestamp]("make_timestamp"), + expression[DatePart]("date_part"), // collection functions expression[CreateArray]("array"), diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala index 1ce493ece18b9..9d43701f03056 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala @@ -1963,3 +1963,90 @@ case class Epoch(child: Expression, timeZoneId: Option[String] = None) defineCodeGen(ctx, ev, c => s"$dtu.getEpoch($c, $zid)") } } + +object DatePart { + + def parseExtractField( + extractField: String, + source: Expression, + errorHandleFunc: => Nothing): Expression = extractField.toUpperCase(Locale.ROOT) match { + case "MILLENNIUM" | "MILLENNIA" | "MIL" | "MILS" => Millennium(source) + case "CENTURY" | "CENTURIES" | "C" | "CENT" => Century(source) + case "DECADE" | "DECADES" | "DEC" | "DECS" => Decade(source) + case "YEAR" | "Y" | "YEARS" | "YR" | "YRS" => Year(source) + case "ISOYEAR" => IsoYear(source) + case "QUARTER" | "QTR" => Quarter(source) + case "MONTH" | "MON" | "MONS" | "MONTHS" => Month(source) + case "WEEK" | "W" | "WEEKS" => WeekOfYear(source) + case "DAY" | "D" | "DAYS" => DayOfMonth(source) + case "DAYOFWEEK" => DayOfWeek(source) + case "DOW" => Subtract(DayOfWeek(source), Literal(1)) + case "ISODOW" => Add(WeekDay(source), Literal(1)) + case "DOY" => DayOfYear(source) + case "HOUR" | "H" | "HOURS" | "HR" | "HRS" => Hour(source) + case "MINUTE" | "M" | "MIN" | "MINS" | "MINUTES" => Minute(source) + case "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" => Second(source) + case "MILLISECONDS" | "MSEC" | "MSECS" | "MILLISECON" | "MSECONDS" | "MS" => + Milliseconds(source) + case "MICROSECONDS" | "USEC" | "USECS" | "USECONDS" | "MICROSECON" | "US" => + Microseconds(source) + case "EPOCH" => Epoch(source) + case _ => errorHandleFunc + } +} + +@ExpressionDescription( + usage = "_FUNC_(field, source) - Extracts a part of the date/timestamp.", + arguments = """ + Arguments: + * field - selects which part of the source should be extracted. Supported string values are: + ["MILLENNIUM", ("MILLENNIA", "MIL", "MILS"), + "CENTURY", ("CENTURIES", "C", "CENT"), + "DECADE", ("DECADES", "DEC", "DECS"), + "YEAR", ("Y", "YEARS", "YR", "YRS"), + "ISOYEAR", + "QUARTER", ("QTR"), + "MONTH", ("MON", "MONS", "MONTHS"), + "WEEK", ("W", "WEEKS"), + "DAY", ("D", "DAYS"), + "DAYOFWEEK", + "DOW", + "ISODOW", + "DOY", + "HOUR", ("H", "HOURS", "HR", "HRS"), + "MINUTE", ("M", "MIN", "MINS", "MINUTES"), + "SECOND", ("S", "SEC", "SECONDS", "SECS"), + "MILLISECONDS", ("MSEC", "MSECS", "MILLISECON", "MSECONDS", "MS"), + "MICROSECONDS", ("USEC", "USECS", "USECONDS", "MICROSECON", "US"), + "EPOCH"] + * source - a date (or timestamp) column from where `field` should be extracted + """, + examples = """ + Examples: + > SELECT _FUNC_('YEAR', TIMESTAMP '2019-08-12 01:00:00.123456'); + 2019 + > SELECT _FUNC_('week', timestamp'2019-08-12 01:00:00.123456'); + 33 + > SELECT _FUNC_('doy', DATE'2019-08-12'); + 224 + """, + since = "3.0.0") +case class DatePart(field: Expression, source: Expression, child: Expression) + extends RuntimeReplaceable { + + def this(field: Expression, source: Expression) { + this(field, source, { + if (!field.foldable) { + throw new AnalysisException("The field parameter needs to be a foldable string value.") + } + val fieldStr = field.eval().asInstanceOf[UTF8String].toString + DatePart.parseExtractField(fieldStr, source, { + throw new AnalysisException(s"Literals of type '$fieldStr' are currently not supported.") + }) + }) + } + + override def flatArguments: Iterator[Any] = Iterator(field, source) + override def sql: String = s"$prettyName(${field.sql}, ${source.sql})" + override def prettyName: String = "date_part" +} diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala index 27579273f08b6..90a533735aed2 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala @@ -1409,48 +1409,12 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging * Create a Extract expression. */ override def visitExtract(ctx: ExtractContext): Expression = withOrigin(ctx) { - ctx.field.getText.toUpperCase(Locale.ROOT) match { - case "MILLENNIUM" | "MILLENNIA" | "MIL" | "MILS" => - Millennium(expression(ctx.source)) - case "CENTURY" | "CENTURIES" | "C" | "CENT" => - Century(expression(ctx.source)) - case "DECADE" | "DECADES" | "DEC" | "DECS" => - Decade(expression(ctx.source)) - case "YEAR" | "Y" | "YEARS" | "YR" | "YRS" => - Year(expression(ctx.source)) - case "ISOYEAR" => - IsoYear(expression(ctx.source)) - case "QUARTER" | "QTR" => - Quarter(expression(ctx.source)) - case "MONTH" | "MON" | "MONS" | "MONTHS" => - Month(expression(ctx.source)) - case "WEEK" | "W" | "WEEKS" => - WeekOfYear(expression(ctx.source)) - case "DAY" | "D" | "DAYS" => - DayOfMonth(expression(ctx.source)) - case "DAYOFWEEK" => - DayOfWeek(expression(ctx.source)) - case "DOW" => - Subtract(DayOfWeek(expression(ctx.source)), Literal(1)) - case "ISODOW" => - Add(WeekDay(expression(ctx.source)), Literal(1)) - case "DOY" => - DayOfYear(expression(ctx.source)) - case "HOUR" | "H" | "HOURS" | "HR" | "HRS" => - Hour(expression(ctx.source)) - case "MINUTE" | "M" | "MIN" | "MINS" | "MINUTES" => - Minute(expression(ctx.source)) - case "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" => - Second(expression(ctx.source)) - case "MILLISECONDS" | "MSEC" | "MSECS" | "MILLISECON" | "MSECONDS" | "MS" => - Milliseconds(expression(ctx.source)) - case "MICROSECONDS" | "USEC" | "USECS" | "USECONDS" | "MICROSECON" | "US" => - Microseconds(expression(ctx.source)) - case "EPOCH" => - Epoch(expression(ctx.source)) - case other => - throw new ParseException(s"Literals of type '$other' are currently not supported.", ctx) - } + val fieldStr = ctx.field.getText + val source = expression(ctx.source) + val extractField = DatePart.parseExtractField(fieldStr, source, { + throw new ParseException(s"Literals of type '$fieldStr' are currently not supported.", ctx) + }) + new DatePart(Literal(fieldStr), expression(ctx.source), extractField) } /** diff --git a/sql/core/src/test/resources/sql-tests/inputs/date_part.sql b/sql/core/src/test/resources/sql-tests/inputs/date_part.sql new file mode 100644 index 0000000000000..cb3d966281009 --- /dev/null +++ b/sql/core/src/test/resources/sql-tests/inputs/date_part.sql @@ -0,0 +1,68 @@ +CREATE TEMPORARY VIEW t AS select '2011-05-06 07:08:09.1234567' as c; + +select date_part('millennium', c) from t; +select date_part('millennia', c) from t; +select date_part('mil', c) from t; +select date_part('mils', c) from t; + +select date_part('century', c) from t; +select date_part('centuries', c) from t; +select date_part('c', c) from t; +select date_part('cent', c) from t; + +select date_part('decade', c) from t; +select date_part('decades', c) from t; +select date_part('dec', c) from t; +select date_part('decs', c) from t; + +select date_part('year', c) from t; +select date_part('y', c) from t; +select date_part('years', c) from t; +select date_part('yr', c) from t; +select date_part('yrs', c) from t; + +select date_part('quarter', c) from t; +select date_part('qtr', c) from t; + +select date_part('month', c) from t; +select date_part('mon', c) from t; +select date_part('mons', c) from t; +select date_part('months', c) from t; + +select date_part('week', c) from t; +select date_part('w', c) from t; +select date_part('weeks', c) from t; + +select date_part('day', c) from t; +select date_part('d', c) from t; +select date_part('days', c) from t; + +select date_part('dayofweek', c) from t; + +select date_part('dow', c) from t; + +select date_part('isodow', c) from t; + +select date_part('doy', c) from t; + +select date_part('hour', c) from t; +select date_part('h', c) from t; +select date_part('hours', c) from t; +select date_part('hr', c) from t; +select date_part('hrs', c) from t; + +select date_part('minute', c) from t; +select date_part('m', c) from t; +select date_part('min', c) from t; +select date_part('mins', c) from t; +select date_part('minutes', c) from t; + +select date_part('second', c) from t; +select date_part('s', c) from t; +select date_part('sec', c) from t; +select date_part('seconds', c) from t; +select date_part('secs', c) from t; + +select date_part('not_supported', c) from t; + +select date_part(c, c) from t; diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/timestamp.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/timestamp.sql index 2b974816766bd..65e8d3280e07c 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/timestamp.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/timestamp.sql @@ -187,22 +187,21 @@ SELECT '' AS date_trunc_week, date_trunc( 'week', timestamp '2004-02-29 15:44:17 -- WHERE d1 BETWEEN timestamp '1902-01-01' -- AND timestamp '2038-01-01'; --- [SPARK-28420] Date/Time Functions: date_part --- SELECT '' AS "54", d1 as "timestamp", --- date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, --- date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, --- date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second --- FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; - --- SELECT '' AS "54", d1 as "timestamp", --- date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, --- date_part( 'usec', d1) AS usec --- FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; - --- SELECT '' AS "54", d1 as "timestamp", --- date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, --- date_part( 'dow', d1) AS dow --- FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'year', d1) AS `year`, date_part( 'month', d1) AS `month`, + date_part( 'day', d1) AS `day`, date_part( 'hour', d1) AS `hour`, + date_part( 'minute', d1) AS `minute`, date_part( 'second', d1) AS `second` + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; + +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; + +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'dow', d1) AS dow + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; -- [SPARK-28137] Data Type Formatting Functions -- TO_CHAR() diff --git a/sql/core/src/test/resources/sql-tests/results/date_part.sql.out b/sql/core/src/test/resources/sql-tests/results/date_part.sql.out new file mode 100644 index 0000000000000..c59dfdbd3da34 --- /dev/null +++ b/sql/core/src/test/resources/sql-tests/results/date_part.sql.out @@ -0,0 +1,412 @@ +-- Automatically generated by SQLQueryTestSuite +-- Number of queries: 51 + + +-- !query 0 +CREATE TEMPORARY VIEW t AS select '2011-05-06 07:08:09.1234567' as c +-- !query 0 schema +struct<> +-- !query 0 output + + + +-- !query 1 +select date_part('millennium', c) from t +-- !query 1 schema +struct +-- !query 1 output +3 + + +-- !query 2 +select date_part('millennia', c) from t +-- !query 2 schema +struct +-- !query 2 output +3 + + +-- !query 3 +select date_part('mil', c) from t +-- !query 3 schema +struct +-- !query 3 output +3 + + +-- !query 4 +select date_part('mils', c) from t +-- !query 4 schema +struct +-- !query 4 output +3 + + +-- !query 5 +select date_part('century', c) from t +-- !query 5 schema +struct +-- !query 5 output +21 + + +-- !query 6 +select date_part('centuries', c) from t +-- !query 6 schema +struct +-- !query 6 output +21 + + +-- !query 7 +select date_part('c', c) from t +-- !query 7 schema +struct +-- !query 7 output +21 + + +-- !query 8 +select date_part('cent', c) from t +-- !query 8 schema +struct +-- !query 8 output +21 + + +-- !query 9 +select date_part('decade', c) from t +-- !query 9 schema +struct +-- !query 9 output +201 + + +-- !query 10 +select date_part('decades', c) from t +-- !query 10 schema +struct +-- !query 10 output +201 + + +-- !query 11 +select date_part('dec', c) from t +-- !query 11 schema +struct +-- !query 11 output +201 + + +-- !query 12 +select date_part('decs', c) from t +-- !query 12 schema +struct +-- !query 12 output +201 + + +-- !query 13 +select date_part('year', c) from t +-- !query 13 schema +struct +-- !query 13 output +2011 + + +-- !query 14 +select date_part('y', c) from t +-- !query 14 schema +struct +-- !query 14 output +2011 + + +-- !query 15 +select date_part('years', c) from t +-- !query 15 schema +struct +-- !query 15 output +2011 + + +-- !query 16 +select date_part('yr', c) from t +-- !query 16 schema +struct +-- !query 16 output +2011 + + +-- !query 17 +select date_part('yrs', c) from t +-- !query 17 schema +struct +-- !query 17 output +2011 + + +-- !query 18 +select date_part('quarter', c) from t +-- !query 18 schema +struct +-- !query 18 output +2 + + +-- !query 19 +select date_part('qtr', c) from t +-- !query 19 schema +struct +-- !query 19 output +2 + + +-- !query 20 +select date_part('month', c) from t +-- !query 20 schema +struct +-- !query 20 output +5 + + +-- !query 21 +select date_part('mon', c) from t +-- !query 21 schema +struct +-- !query 21 output +5 + + +-- !query 22 +select date_part('mons', c) from t +-- !query 22 schema +struct +-- !query 22 output +5 + + +-- !query 23 +select date_part('months', c) from t +-- !query 23 schema +struct +-- !query 23 output +5 + + +-- !query 24 +select date_part('week', c) from t +-- !query 24 schema +struct +-- !query 24 output +18 + + +-- !query 25 +select date_part('w', c) from t +-- !query 25 schema +struct +-- !query 25 output +18 + + +-- !query 26 +select date_part('weeks', c) from t +-- !query 26 schema +struct +-- !query 26 output +18 + + +-- !query 27 +select date_part('day', c) from t +-- !query 27 schema +struct +-- !query 27 output +6 + + +-- !query 28 +select date_part('d', c) from t +-- !query 28 schema +struct +-- !query 28 output +6 + + +-- !query 29 +select date_part('days', c) from t +-- !query 29 schema +struct +-- !query 29 output +6 + + +-- !query 30 +select date_part('dayofweek', c) from t +-- !query 30 schema +struct +-- !query 30 output +6 + + +-- !query 31 +select date_part('dow', c) from t +-- !query 31 schema +struct +-- !query 31 output +5 + + +-- !query 32 +select date_part('isodow', c) from t +-- !query 32 schema +struct +-- !query 32 output +5 + + +-- !query 33 +select date_part('doy', c) from t +-- !query 33 schema +struct +-- !query 33 output +126 + + +-- !query 34 +select date_part('hour', c) from t +-- !query 34 schema +struct +-- !query 34 output +7 + + +-- !query 35 +select date_part('h', c) from t +-- !query 35 schema +struct +-- !query 35 output +7 + + +-- !query 36 +select date_part('hours', c) from t +-- !query 36 schema +struct +-- !query 36 output +7 + + +-- !query 37 +select date_part('hr', c) from t +-- !query 37 schema +struct +-- !query 37 output +7 + + +-- !query 38 +select date_part('hrs', c) from t +-- !query 38 schema +struct +-- !query 38 output +7 + + +-- !query 39 +select date_part('minute', c) from t +-- !query 39 schema +struct +-- !query 39 output +8 + + +-- !query 40 +select date_part('m', c) from t +-- !query 40 schema +struct +-- !query 40 output +8 + + +-- !query 41 +select date_part('min', c) from t +-- !query 41 schema +struct +-- !query 41 output +8 + + +-- !query 42 +select date_part('mins', c) from t +-- !query 42 schema +struct +-- !query 42 output +8 + + +-- !query 43 +select date_part('minutes', c) from t +-- !query 43 schema +struct +-- !query 43 output +8 + + +-- !query 44 +select date_part('second', c) from t +-- !query 44 schema +struct +-- !query 44 output +9 + + +-- !query 45 +select date_part('s', c) from t +-- !query 45 schema +struct +-- !query 45 output +9 + + +-- !query 46 +select date_part('sec', c) from t +-- !query 46 schema +struct +-- !query 46 output +9 + + +-- !query 47 +select date_part('seconds', c) from t +-- !query 47 schema +struct +-- !query 47 output +9 + + +-- !query 48 +select date_part('secs', c) from t +-- !query 48 schema +struct +-- !query 48 output +9 + + +-- !query 49 +select date_part('not_supported', c) from t +-- !query 49 schema +struct<> +-- !query 49 output +org.apache.spark.sql.AnalysisException +Literals of type 'not_supported' are currently not supported.;; line 1 pos 7 + + +-- !query 50 +select date_part(c, c) from t +-- !query 50 schema +struct<> +-- !query 50 output +org.apache.spark.sql.AnalysisException +The field parameter needs to be a foldable string value.;; line 1 pos 7 diff --git a/sql/core/src/test/resources/sql-tests/results/extract.sql.out b/sql/core/src/test/resources/sql-tests/results/extract.sql.out index b02dfe054344b..e007fa8368ef5 100644 --- a/sql/core/src/test/resources/sql-tests/results/extract.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/extract.sql.out @@ -13,7 +13,7 @@ struct<> -- !query 1 select extract(millennium from c) from t -- !query 1 schema -struct +struct -- !query 1 output 3 @@ -21,7 +21,7 @@ struct -- !query 2 select extract(millennia from c) from t -- !query 2 schema -struct +struct -- !query 2 output 3 @@ -29,7 +29,7 @@ struct -- !query 3 select extract(mil from c) from t -- !query 3 schema -struct +struct -- !query 3 output 3 @@ -37,7 +37,7 @@ struct -- !query 4 select extract(mils from c) from t -- !query 4 schema -struct +struct -- !query 4 output 3 @@ -45,7 +45,7 @@ struct -- !query 5 select extract(century from c) from t -- !query 5 schema -struct +struct -- !query 5 output 21 @@ -53,7 +53,7 @@ struct -- !query 6 select extract(centuries from c) from t -- !query 6 schema -struct +struct -- !query 6 output 21 @@ -61,7 +61,7 @@ struct -- !query 7 select extract(c from c) from t -- !query 7 schema -struct +struct -- !query 7 output 21 @@ -69,7 +69,7 @@ struct -- !query 8 select extract(cent from c) from t -- !query 8 schema -struct +struct -- !query 8 output 21 @@ -77,7 +77,7 @@ struct -- !query 9 select extract(decade from c) from t -- !query 9 schema -struct +struct -- !query 9 output 201 @@ -85,7 +85,7 @@ struct -- !query 10 select extract(decades from c) from t -- !query 10 schema -struct +struct -- !query 10 output 201 @@ -93,7 +93,7 @@ struct -- !query 11 select extract(dec from c) from t -- !query 11 schema -struct +struct -- !query 11 output 201 @@ -101,7 +101,7 @@ struct -- !query 12 select extract(decs from c) from t -- !query 12 schema -struct +struct -- !query 12 output 201 @@ -109,7 +109,7 @@ struct -- !query 13 select extract(year from c) from t -- !query 13 schema -struct +struct -- !query 13 output 2011 @@ -117,7 +117,7 @@ struct -- !query 14 select extract(y from c) from t -- !query 14 schema -struct +struct -- !query 14 output 2011 @@ -125,7 +125,7 @@ struct -- !query 15 select extract(years from c) from t -- !query 15 schema -struct +struct -- !query 15 output 2011 @@ -133,7 +133,7 @@ struct -- !query 16 select extract(yr from c) from t -- !query 16 schema -struct +struct -- !query 16 output 2011 @@ -141,7 +141,7 @@ struct -- !query 17 select extract(yrs from c) from t -- !query 17 schema -struct +struct -- !query 17 output 2011 @@ -149,7 +149,7 @@ struct -- !query 18 select extract(isoyear from c) from t -- !query 18 schema -struct +struct -- !query 18 output 2011 @@ -157,7 +157,7 @@ struct -- !query 19 select extract(quarter from c) from t -- !query 19 schema -struct +struct -- !query 19 output 2 @@ -165,7 +165,7 @@ struct -- !query 20 select extract(qtr from c) from t -- !query 20 schema -struct +struct -- !query 20 output 2 @@ -173,7 +173,7 @@ struct -- !query 21 select extract(month from c) from t -- !query 21 schema -struct +struct -- !query 21 output 5 @@ -181,7 +181,7 @@ struct -- !query 22 select extract(mon from c) from t -- !query 22 schema -struct +struct -- !query 22 output 5 @@ -189,7 +189,7 @@ struct -- !query 23 select extract(mons from c) from t -- !query 23 schema -struct +struct -- !query 23 output 5 @@ -197,7 +197,7 @@ struct -- !query 24 select extract(months from c) from t -- !query 24 schema -struct +struct -- !query 24 output 5 @@ -205,7 +205,7 @@ struct -- !query 25 select extract(week from c) from t -- !query 25 schema -struct +struct -- !query 25 output 18 @@ -213,7 +213,7 @@ struct -- !query 26 select extract(w from c) from t -- !query 26 schema -struct +struct -- !query 26 output 18 @@ -221,7 +221,7 @@ struct -- !query 27 select extract(weeks from c) from t -- !query 27 schema -struct +struct -- !query 27 output 18 @@ -229,7 +229,7 @@ struct -- !query 28 select extract(day from c) from t -- !query 28 schema -struct +struct -- !query 28 output 6 @@ -237,7 +237,7 @@ struct -- !query 29 select extract(d from c) from t -- !query 29 schema -struct +struct -- !query 29 output 6 @@ -245,7 +245,7 @@ struct -- !query 30 select extract(days from c) from t -- !query 30 schema -struct +struct -- !query 30 output 6 @@ -253,7 +253,7 @@ struct -- !query 31 select extract(dayofweek from c) from t -- !query 31 schema -struct +struct -- !query 31 output 6 @@ -261,7 +261,7 @@ struct -- !query 32 select extract(dow from c) from t -- !query 32 schema -struct<(dayofweek(CAST(c AS DATE)) - 1):int> +struct -- !query 32 output 5 @@ -269,7 +269,7 @@ struct<(dayofweek(CAST(c AS DATE)) - 1):int> -- !query 33 select extract(isodow from c) from t -- !query 33 schema -struct<(weekday(CAST(c AS DATE)) + 1):int> +struct -- !query 33 output 5 @@ -277,7 +277,7 @@ struct<(weekday(CAST(c AS DATE)) + 1):int> -- !query 34 select extract(doy from c) from t -- !query 34 schema -struct +struct -- !query 34 output 126 @@ -285,7 +285,7 @@ struct -- !query 35 select extract(hour from c) from t -- !query 35 schema -struct +struct -- !query 35 output 7 @@ -293,7 +293,7 @@ struct -- !query 36 select extract(h from c) from t -- !query 36 schema -struct +struct -- !query 36 output 7 @@ -301,7 +301,7 @@ struct -- !query 37 select extract(hours from c) from t -- !query 37 schema -struct +struct -- !query 37 output 7 @@ -309,7 +309,7 @@ struct -- !query 38 select extract(hr from c) from t -- !query 38 schema -struct +struct -- !query 38 output 7 @@ -317,7 +317,7 @@ struct -- !query 39 select extract(hrs from c) from t -- !query 39 schema -struct +struct -- !query 39 output 7 @@ -325,7 +325,7 @@ struct -- !query 40 select extract(minute from c) from t -- !query 40 schema -struct +struct -- !query 40 output 8 @@ -333,7 +333,7 @@ struct -- !query 41 select extract(m from c) from t -- !query 41 schema -struct +struct -- !query 41 output 8 @@ -341,7 +341,7 @@ struct -- !query 42 select extract(min from c) from t -- !query 42 schema -struct +struct -- !query 42 output 8 @@ -349,7 +349,7 @@ struct -- !query 43 select extract(mins from c) from t -- !query 43 schema -struct +struct -- !query 43 output 8 @@ -357,7 +357,7 @@ struct -- !query 44 select extract(minutes from c) from t -- !query 44 schema -struct +struct -- !query 44 output 8 @@ -365,7 +365,7 @@ struct -- !query 45 select extract(second from c) from t -- !query 45 schema -struct +struct -- !query 45 output 9 @@ -373,7 +373,7 @@ struct -- !query 46 select extract(s from c) from t -- !query 46 schema -struct +struct -- !query 46 output 9 @@ -381,7 +381,7 @@ struct -- !query 47 select extract(sec from c) from t -- !query 47 schema -struct +struct -- !query 47 output 9 @@ -389,7 +389,7 @@ struct -- !query 48 select extract(seconds from c) from t -- !query 48 schema -struct +struct -- !query 48 output 9 @@ -397,7 +397,7 @@ struct -- !query 49 select extract(secs from c) from t -- !query 49 schema -struct +struct -- !query 49 output 9 @@ -405,7 +405,7 @@ struct -- !query 50 select extract(milliseconds from c) from t -- !query 50 schema -struct +struct -- !query 50 output 9123.456 @@ -413,7 +413,7 @@ struct -- !query 51 select extract(msec from c) from t -- !query 51 schema -struct +struct -- !query 51 output 9123.456 @@ -421,7 +421,7 @@ struct -- !query 52 select extract(msecs from c) from t -- !query 52 schema -struct +struct -- !query 52 output 9123.456 @@ -429,7 +429,7 @@ struct -- !query 53 select extract(millisecon from c) from t -- !query 53 schema -struct +struct -- !query 53 output 9123.456 @@ -437,7 +437,7 @@ struct -- !query 54 select extract(mseconds from c) from t -- !query 54 schema -struct +struct -- !query 54 output 9123.456 @@ -445,7 +445,7 @@ struct -- !query 55 select extract(ms from c) from t -- !query 55 schema -struct +struct -- !query 55 output 9123.456 @@ -453,7 +453,7 @@ struct -- !query 56 select extract(microseconds from c) from t -- !query 56 schema -struct +struct -- !query 56 output 9123456 @@ -461,7 +461,7 @@ struct -- !query 57 select extract(usec from c) from t -- !query 57 schema -struct +struct -- !query 57 output 9123456 @@ -469,7 +469,7 @@ struct -- !query 58 select extract(usecs from c) from t -- !query 58 schema -struct +struct -- !query 58 output 9123456 @@ -477,7 +477,7 @@ struct -- !query 59 select extract(useconds from c) from t -- !query 59 schema -struct +struct -- !query 59 output 9123456 @@ -485,7 +485,7 @@ struct -- !query 60 select extract(microsecon from c) from t -- !query 60 schema -struct +struct -- !query 60 output 9123456 @@ -493,7 +493,7 @@ struct -- !query 61 select extract(us from c) from t -- !query 61 schema -struct +struct -- !query 61 output 9123456 @@ -501,7 +501,7 @@ struct -- !query 62 select extract(epoch from c) from t -- !query 62 schema -struct +struct -- !query 62 output 1304665689.123456 @@ -513,7 +513,7 @@ struct<> -- !query 63 output org.apache.spark.sql.catalyst.parser.ParseException -Literals of type 'NOT_SUPPORTED' are currently not supported.(line 1, pos 7) +Literals of type 'not_supported' are currently not supported.(line 1, pos 7) == SQL == select extract(not_supported from c) from t diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/date.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/date.sql.out index cb2be6d1cd22d..083832007d618 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/date.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/date.sql.out @@ -504,7 +504,7 @@ struct -- !query 47 SELECT EXTRACT(EPOCH FROM DATE '1970-01-01') -- !query 47 schema -struct +struct -- !query 47 output 0 @@ -512,7 +512,7 @@ struct -- !query 48 SELECT EXTRACT(EPOCH FROM TIMESTAMP '1970-01-01') -- !query 48 schema -struct +struct -- !query 48 output 0 @@ -520,7 +520,7 @@ struct -- !query 49 SELECT EXTRACT(CENTURY FROM TO_DATE('0101-12-31 BC', 'yyyy-MM-dd G')) -- !query 49 schema -struct +struct -- !query 49 output -2 @@ -528,7 +528,7 @@ struct -- !query 50 SELECT EXTRACT(CENTURY FROM TO_DATE('0100-12-31 BC', 'yyyy-MM-dd G')) -- !query 50 schema -struct +struct -- !query 50 output -1 @@ -536,7 +536,7 @@ struct -- !query 51 SELECT EXTRACT(CENTURY FROM TO_DATE('0001-12-31 BC', 'yyyy-MM-dd G')) -- !query 51 schema -struct +struct -- !query 51 output -1 @@ -544,7 +544,7 @@ struct -- !query 52 SELECT EXTRACT(CENTURY FROM DATE '0001-01-01') -- !query 52 schema -struct +struct -- !query 52 output 1 @@ -552,7 +552,7 @@ struct -- !query 53 SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD') -- !query 53 schema -struct +struct -- !query 53 output 1 @@ -560,7 +560,7 @@ struct -- !query 54 SELECT EXTRACT(CENTURY FROM DATE '1900-12-31') -- !query 54 schema -struct +struct -- !query 54 output 19 @@ -568,7 +568,7 @@ struct -- !query 55 SELECT EXTRACT(CENTURY FROM DATE '1901-01-01') -- !query 55 schema -struct +struct -- !query 55 output 20 @@ -576,7 +576,7 @@ struct -- !query 56 SELECT EXTRACT(CENTURY FROM DATE '2000-12-31') -- !query 56 schema -struct +struct -- !query 56 output 20 @@ -584,7 +584,7 @@ struct -- !query 57 SELECT EXTRACT(CENTURY FROM DATE '2001-01-01') -- !query 57 schema -struct +struct -- !query 57 output 21 @@ -600,7 +600,7 @@ true -- !query 59 SELECT EXTRACT(MILLENNIUM FROM TO_DATE('0001-12-31 BC', 'yyyy-MM-dd G')) -- !query 59 schema -struct +struct -- !query 59 output -1 @@ -608,7 +608,7 @@ struct -- !query 60 SELECT EXTRACT(MILLENNIUM FROM DATE '0001-01-01 AD') -- !query 60 schema -struct +struct -- !query 60 output 1 @@ -616,7 +616,7 @@ struct -- !query 61 SELECT EXTRACT(MILLENNIUM FROM DATE '1000-12-31') -- !query 61 schema -struct +struct -- !query 61 output 1 @@ -624,7 +624,7 @@ struct -- !query 62 SELECT EXTRACT(MILLENNIUM FROM DATE '1001-01-01') -- !query 62 schema -struct +struct -- !query 62 output 2 @@ -632,7 +632,7 @@ struct -- !query 63 SELECT EXTRACT(MILLENNIUM FROM DATE '2000-12-31') -- !query 63 schema -struct +struct -- !query 63 output 2 @@ -640,7 +640,7 @@ struct -- !query 64 SELECT EXTRACT(MILLENNIUM FROM DATE '2001-01-01') -- !query 64 schema -struct +struct -- !query 64 output 3 @@ -648,7 +648,7 @@ struct -- !query 65 SELECT EXTRACT(MILLENNIUM FROM CURRENT_DATE) -- !query 65 schema -struct +struct -- !query 65 output 3 @@ -656,7 +656,7 @@ struct -- !query 66 SELECT EXTRACT(DECADE FROM DATE '1994-12-25') -- !query 66 schema -struct +struct -- !query 66 output 199 @@ -664,7 +664,7 @@ struct -- !query 67 SELECT EXTRACT(DECADE FROM DATE '0010-01-01') -- !query 67 schema -struct +struct -- !query 67 output 1 @@ -672,7 +672,7 @@ struct -- !query 68 SELECT EXTRACT(DECADE FROM DATE '0009-12-31') -- !query 68 schema -struct +struct -- !query 68 output 0 @@ -680,7 +680,7 @@ struct -- !query 69 SELECT EXTRACT(DECADE FROM TO_DATE('0001-01-01 BC', 'yyyy-MM-dd G')) -- !query 69 schema -struct +struct -- !query 69 output 0 @@ -688,7 +688,7 @@ struct -- !query 70 SELECT EXTRACT(DECADE FROM TO_DATE('0002-12-31 BC', 'yyyy-MM-dd G')) -- !query 70 schema -struct +struct -- !query 70 output -1 @@ -696,7 +696,7 @@ struct -- !query 71 SELECT EXTRACT(DECADE FROM TO_DATE('0011-01-01 BC', 'yyyy-MM-dd G')) -- !query 71 schema -struct +struct -- !query 71 output -1 @@ -704,7 +704,7 @@ struct -- !query 72 SELECT EXTRACT(DECADE FROM TO_DATE('0012-12-31 BC', 'yyyy-MM-dd G')) -- !query 72 schema -struct +struct -- !query 72 output -2 @@ -720,7 +720,7 @@ true -- !query 74 SELECT EXTRACT(CENTURY FROM TIMESTAMP '1970-03-20 04:30:00.00000') -- !query 74 schema -struct +struct -- !query 74 output 20 diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/timestamp.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/timestamp.sql.out index 13a1d09b71b76..75d9ee8d9c797 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/timestamp.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/timestamp.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 15 +-- Number of queries: 18 -- !query 0 @@ -123,16 +123,59 @@ struct -- !query 13 -SELECT make_timestamp(2014,12,28,6,30,45.887) +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'year', d1) AS `year`, date_part( 'month', d1) AS `month`, + date_part( 'day', d1) AS `day`, date_part( 'hour', d1) AS `hour`, + date_part( 'minute', d1) AS `minute`, date_part( 'second', d1) AS `second` + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' -- !query 13 schema -struct +struct<54:string,timestamp:timestamp,year:int,month:int,day:int,hour:int,minute:int,second:int> -- !query 13 output -2014-12-28 06:30:45.887 + 1997-01-02 00:00:00 1997 1 2 0 0 0 + 1997-01-02 03:04:05 1997 1 2 3 4 5 + 1997-02-10 17:32:01 1997 2 10 17 32 1 + 2001-09-22 18:19:20 2001 9 22 18 19 20 -- !query 14 -DROP TABLE TIMESTAMP_TBL +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' -- !query 14 schema -struct<> +struct<54:string,timestamp:timestamp,quarter:int,msec:decimal(8,3),usec:int> -- !query 14 output + 1997-01-02 00:00:00 1 0 0 + 1997-01-02 03:04:05 1 5000 5000000 + 1997-02-10 17:32:01 1 1000 1000000 + 2001-09-22 18:19:20 3 20000 20000000 + + +-- !query 15 +SELECT '' AS `54`, d1 as `timestamp`, + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'dow', d1) AS dow + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01' +-- !query 15 schema +struct<54:string,timestamp:timestamp,isoyear:int,week:int,dow:int> +-- !query 15 output + 1997-01-02 00:00:00 1997 1 4 + 1997-01-02 03:04:05 1997 1 4 + 1997-02-10 17:32:01 1997 7 1 + 2001-09-22 18:19:20 2001 38 6 + + +-- !query 16 +SELECT make_timestamp(2014,12,28,6,30,45.887) +-- !query 16 schema +struct +-- !query 16 output +2014-12-28 06:30:45.887 + + +-- !query 17 +DROP TABLE TIMESTAMP_TBL +-- !query 17 schema +struct<> +-- !query 17 output