Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.spark.sql.catalyst.util

import java.math.{BigDecimal, RoundingMode}
import java.util.concurrent.TimeUnit

import scala.util.control.NonFatal
Expand Down Expand Up @@ -255,26 +256,50 @@ object IntervalUtils {
try {
units(i) match {
case "year" =>
months = Math.addExact(months, Math.multiplyExact(values(i).toInt, 12))
months = new BigDecimal(values(i)).multiply(new BigDecimal(MONTHS_PER_YEAR))
.setScale(0, RoundingMode.DOWN)
.intValueExact
case "month" =>
months = Math.addExact(months, values(i).toInt)
val m = new BigDecimal(values(i))
microseconds = m.remainder(BigDecimal.ONE).multiply(new BigDecimal(MICROS_PER_MONTH))
.setScale(0, RoundingMode.DOWN)
.longValueExact
months = Math.addExact(months, m.setScale(0, RoundingMode.DOWN).intValueExact)
case "week" =>
val weeksUs = Math.multiplyExact(values(i).toLong, 7 * DateTimeUtils.MICROS_PER_DAY)
microseconds = Math.addExact(microseconds, weeksUs)
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(7 * DateTimeUtils.MICROS_PER_DAY))
.setScale(0, RoundingMode.DOWN)
.longValueExact)
case "day" =>
val daysUs = Math.multiplyExact(values(i).toLong, DateTimeUtils.MICROS_PER_DAY)
microseconds = Math.addExact(microseconds, daysUs)
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(DateTimeUtils.MICROS_PER_DAY))
.setScale(0, RoundingMode.DOWN)
.longValueExact)
case "hour" =>
val hoursUs = Math.multiplyExact(values(i).toLong, MICROS_PER_HOUR)
microseconds = Math.addExact(microseconds, hoursUs)
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(MICROS_PER_HOUR))
.setScale(0, RoundingMode.DOWN)
.longValueExact)
case "minute" =>
val minutesUs = Math.multiplyExact(values(i).toLong, MICROS_PER_MINUTE)
microseconds = Math.addExact(microseconds, minutesUs)
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(MICROS_PER_MINUTE))
.setScale(0, RoundingMode.DOWN)
.longValueExact)
case "second" =>
microseconds = Math.addExact(microseconds, parseSecondNano(values(i)))
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(DateTimeUtils.MICROS_PER_SECOND))
.setScale(0, RoundingMode.DOWN).longValueExact)
case "millisecond" =>
val millisUs = Math.multiplyExact(values(i).toLong, DateTimeUtils.MICROS_PER_MILLIS)
microseconds = Math.addExact(microseconds, millisUs)
microseconds = Math.addExact(
microseconds,
new BigDecimal(values(i)).multiply(new BigDecimal(DateTimeUtils.MICROS_PER_MILLIS))
.setScale(0, RoundingMode.DOWN)
.longValueExact)
case "microsecond" =>
microseconds = Math.addExact(microseconds, values(i).toLong)
}
Expand Down
24 changes: 24 additions & 0 deletions sql/core/src/test/resources/sql-tests/inputs/datetime.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,27 @@ select date '2001-10-01' - 7;
select date '2001-10-01' - date '2001-09-28';
select date'2020-01-01' - timestamp'2019-10-06 10:11:12.345678';
select timestamp'2019-10-06 10:11:12.345678' - date'2020-01-01';

-- year interval only affect year and month if any
select interval '1.41 years';

-- month interval will affect microseconds
select interval '2.512345678 months';
select interval '2.51 months';

select interval '2.21 weeks';
select interval '15.24 days';
select interval '3.31 hours';
select interval '5.38 minutes';
select interval '12.3456789 seconds';
select interval '-12.3456789 seconds';

select interval '6.66 milliseconds';

select interval '1.41 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds';
select interval '1.42 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds';

select interval '-1.41 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds';
select interval '-1.42 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds';

select interval '.1111111111' second;
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
-- SELECT INTERVAL '-1 +02:03' AS `22 hours ago...`;
-- SELECT INTERVAL '-1 days +02:03' AS `22 hours ago...`;
-- [SPARK-29371] Support interval field values with fractional parts
-- SELECT INTERVAL '1.5 weeks' AS `Ten days twelve hours`;
-- SELECT INTERVAL '1.5 months' AS `One month 15 days`;
SELECT INTERVAL '1.5 weeks' AS `Ten days twelve hours`;
SELECT INTERVAL '1.5 months' AS `One month 15 days`;
-- SELECT INTERVAL '10 years -11 month -12 days +13:14' AS `9 years...`;
SELECT INTERVAL '10 years -11 month -12 days +13 hours 14 minutes' AS `9 years...`;

-- [SPARK-29382] Support writing `INTERVAL` type to datasource table
-- CREATE TABLE INTERVAL_TBL (f1 interval);
Expand Down
122 changes: 121 additions & 1 deletion sql/core/src/test/resources/sql-tests/results/datetime.sql.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 17
-- Number of queries: 32


-- !query 0
Expand Down Expand Up @@ -145,3 +145,123 @@ select timestamp'2019-10-06 10:11:12.345678' - date'2020-01-01'
struct<subtracttimestamps(TIMESTAMP('2019-10-06 10:11:12.345678'), CAST(DATE '2020-01-01' AS TIMESTAMP)):interval>
-- !query 16 output
interval -12 weeks -2 days -14 hours -48 minutes -47 seconds -654 milliseconds -322 microseconds


-- !query 17
select interval '1.41 years'
-- !query 17 schema
struct<interval 1 years 4 months:interval>
-- !query 17 output
interval 1 years 4 months


-- !query 18
select interval '2.512345678 months'
-- !query 18 schema
struct<interval 2 months 2 weeks 1 days 8 hours 53 minutes 19 seconds 997 milliseconds 376 microseconds:interval>
-- !query 18 output
interval 2 months 2 weeks 1 days 8 hours 53 minutes 19 seconds 997 milliseconds 376 microseconds


-- !query 19
select interval '2.51 months'
-- !query 19 schema
struct<interval 2 months 2 weeks 1 days 7 hours 12 minutes:interval>
-- !query 19 output
interval 2 months 2 weeks 1 days 7 hours 12 minutes


-- !query 20
select interval '2.21 weeks'
-- !query 20 schema
struct<interval 2 weeks 1 days 11 hours 16 minutes 48 seconds:interval>
-- !query 20 output
interval 2 weeks 1 days 11 hours 16 minutes 48 seconds


-- !query 21
select interval '15.24 days'
-- !query 21 schema
struct<interval 2 weeks 1 days 5 hours 45 minutes 36 seconds:interval>
-- !query 21 output
interval 2 weeks 1 days 5 hours 45 minutes 36 seconds


-- !query 22
select interval '3.31 hours'
-- !query 22 schema
struct<interval 3 hours 18 minutes 36 seconds:interval>
-- !query 22 output
interval 3 hours 18 minutes 36 seconds


-- !query 23
select interval '5.38 minutes'
-- !query 23 schema
struct<interval 5 minutes 22 seconds 800 milliseconds:interval>
-- !query 23 output
interval 5 minutes 22 seconds 800 milliseconds


-- !query 24
select interval '12.3456789 seconds'
-- !query 24 schema
struct<interval 12 seconds 345 milliseconds 678 microseconds:interval>
-- !query 24 output
interval 12 seconds 345 milliseconds 678 microseconds


-- !query 25
select interval '-12.3456789 seconds'
-- !query 25 schema
struct<interval -12 seconds -345 milliseconds -678 microseconds:interval>
-- !query 25 output
interval -12 seconds -345 milliseconds -678 microseconds


-- !query 26
select interval '6.66 milliseconds'
-- !query 26 schema
struct<interval 6 milliseconds 660 microseconds:interval>
-- !query 26 output
interval 6 milliseconds 660 microseconds


-- !query 27
select interval '1.41 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds'
-- !query 27 schema
struct<interval 1 years 6 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds:interval>
-- !query 27 output
interval 1 years 6 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds


-- !query 28
select interval '1.42 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds'
-- !query 28 schema
struct<interval 1 years 7 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds:interval>
-- !query 28 output
interval 1 years 7 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds


-- !query 29
select interval '-1.41 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds'
-- !query 29 schema
struct<interval -1 years -2 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds:interval>
-- !query 29 output
interval -1 years -2 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds


-- !query 30
select interval '-1.42 years 2.51 months 2.21 weeks 15.24 days 3.31 hours 5.38 minutes 12.3456789 seconds'
-- !query 30 schema
struct<interval -1 years -3 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds:interval>
-- !query 30 output
interval -1 years -3 months 6 weeks 4 days 3 hours 38 minutes 35 seconds 145 milliseconds 678 microseconds


-- !query 31
select interval '.1111111111' second
-- !query 31 schema
struct<interval 111 milliseconds 111 microseconds:interval>
-- !query 31 output
interval 111 milliseconds 111 microseconds
Loading