Skip to content

Commit 6224ce4

Browse files
author
Davies Liu
committed
fix conclict
1 parent bd18cd4 commit 6224ce4

File tree

7 files changed

+70
-29
lines changed

7 files changed

+70
-29
lines changed

python/pyspark/sql/functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ def months_between(date1, date2):
882882
883883
>>> df = sqlContext.createDataFrame([('1997-02-28 10:30:00', '1996-10-30')], ['t', 'd'])
884884
>>> df.select(months_between(df.t, df.d).alias('months')).collect()
885-
[Row(months=3.94959677)]
885+
[Row(months=3.9495967...)]
886886
"""
887887
sc = SparkContext._active_spark_context
888888
return Column(sc._jvm.functions.months_between(_to_java_column(date1), _to_java_column(date2)))

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -640,20 +640,23 @@ object HiveTypeCoercion {
640640
}
641641

642642
/**
643-
* Turns Add/Subtract of DateType/TimestampType and IntervalType to TimeAdd/TimeSub
643+
* Turns Add/Subtract of DateType/TimestampType/StringType and CalendarIntervalType
644+
* to TimeAdd/TimeSub
644645
*/
645646
object DateTimeOperations extends Rule[LogicalPlan] {
647+
648+
private val acceptedTypes = Seq(DateType, TimestampType, StringType)
649+
646650
def apply(plan: LogicalPlan): LogicalPlan = plan transformAllExpressions {
647651
// Skip nodes who's children have not been resolved yet.
648652
case e if !e.childrenResolved => e
649653

650-
case Add(left, right) if left.dataType == IntervalType =>
651-
Add(right, left) // switch the order
652-
653-
case Add(left, right) if right.dataType == IntervalType =>
654-
Cast(TimeAdd(Cast(left, TimestampType), right), left.dataType)
655-
case Subtract(left, right) if right.dataType == IntervalType =>
656-
Cast(TimeSub(Cast(left, TimestampType), right), left.dataType)
654+
case Add(l @ CalendarIntervalType(), r) if acceptedTypes.contains(r.dataType) =>
655+
Cast(TimeAdd(r, l), r.dataType)
656+
case Add(l, r @ CalendarIntervalType()) if acceptedTypes.contains(l.dataType) =>
657+
Cast(TimeAdd(l, r), l.dataType)
658+
case Subtract(l, r @ CalendarIntervalType()) if acceptedTypes.contains(l.dataType) =>
659+
Cast(TimeSub(l, r), l.dataType)
657660
}
658661
}
659662

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeFunctions.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import org.apache.spark.sql.catalyst.InternalRow
2626
import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback
2727
import org.apache.spark.sql.catalyst.util.DateTimeUtils
2828
import org.apache.spark.sql.types._
29-
import org.apache.spark.unsafe.types.{Interval, UTF8String}
29+
import org.apache.spark.unsafe.types.{CalendarInterval, UTF8String}
3030

3131
/**
3232
* Returns the current date at the start of query evaluation.
@@ -382,18 +382,18 @@ case class NextDay(startDate: Expression, dayOfWeek: Expression)
382382
* Adds an interval to timestamp.
383383
*/
384384
case class TimeAdd(start: Expression, interval: Expression)
385-
extends BinaryExpression with ExpectsInputTypes {
385+
extends BinaryExpression with ImplicitCastInputTypes {
386386

387387
override def left: Expression = start
388388
override def right: Expression = interval
389389

390390
override def toString: String = s"$left + $right"
391-
override def inputTypes: Seq[AbstractDataType] = Seq(TimestampType, IntervalType)
391+
override def inputTypes: Seq[AbstractDataType] = Seq(TimestampType, CalendarIntervalType)
392392

393393
override def dataType: DataType = TimestampType
394394

395395
override def nullSafeEval(start: Any, interval: Any): Any = {
396-
val itvl = interval.asInstanceOf[Interval]
396+
val itvl = interval.asInstanceOf[CalendarInterval]
397397
DateTimeUtils.timestampAddInterval(
398398
start.asInstanceOf[Long], itvl.months, itvl.microseconds)
399399
}
@@ -410,18 +410,18 @@ case class TimeAdd(start: Expression, interval: Expression)
410410
* Subtracts an interval from timestamp.
411411
*/
412412
case class TimeSub(start: Expression, interval: Expression)
413-
extends BinaryExpression with ExpectsInputTypes {
413+
extends BinaryExpression with ImplicitCastInputTypes {
414414

415415
override def left: Expression = start
416416
override def right: Expression = interval
417417

418418
override def toString: String = s"$left - $right"
419-
override def inputTypes: Seq[AbstractDataType] = Seq(TimestampType, IntervalType)
419+
override def inputTypes: Seq[AbstractDataType] = Seq(TimestampType, CalendarIntervalType)
420420

421421
override def dataType: DataType = TimestampType
422422

423423
override def nullSafeEval(start: Any, interval: Any): Any = {
424-
val itvl = interval.asInstanceOf[Interval]
424+
val itvl = interval.asInstanceOf[CalendarInterval]
425425
DateTimeUtils.timestampAddInterval(
426426
start.asInstanceOf[Long], 0 - itvl.months, 0 - itvl.microseconds)
427427
}

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/util/DateTimeUtils.scala

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,22 +587,22 @@ object DateTimeUtils {
587587
private def firstDayOfMonth(absoluteMonth: Int): Int = {
588588
val absoluteYear = absoluteMonth / 12
589589
var monthInYear = absoluteMonth - absoluteYear * 12
590-
var days = getDaysFromYears(absoluteYear)
590+
var date = getDateFromYear(absoluteYear)
591591
if (monthInYear >= 2 && isLeapYear(absoluteYear + YearZero)) {
592-
days += 1
592+
date += 1
593593
}
594594
while (monthInYear > 0) {
595-
days += monthDays(monthInYear - 1)
595+
date += monthDays(monthInYear - 1)
596596
monthInYear -= 1
597597
}
598-
days
598+
date
599599
}
600600

601601
/**
602602
* Returns the date value for January 1 of the given year.
603603
* The year is expressed in years since year zero (17999 BC), starting from 0.
604604
*/
605-
private def getDaysFromYears(absoluteYear: Int): Int = {
605+
private def getDateFromYear(absoluteYear: Int): Int = {
606606
val absoluteDays = (absoluteYear * 365 + absoluteYear / 400 - absoluteYear / 100
607607
+ absoluteYear / 4)
608608
absoluteDays - toYearZero
@@ -681,7 +681,13 @@ object DateTimeUtils {
681681

682682
/**
683683
* Returns number of months between time1 and time2. time1 and time2 are expressed in
684-
* microseconds since 1.1.1970
684+
* microseconds since 1.1.1970.
685+
*
686+
* If time1 and time2 having the same day of month, or both are the last day of month,
687+
* it returns an integer (time under a day will be ignored).
688+
*
689+
* Otherwise, the difference is calculated based on 31 days per month, and rounding to
690+
* 8 digits.
685691
*/
686692
def monthsBetween(time1: Long, time2: Long): Double = {
687693
val millis1 = time1 / 1000L

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercionSuite.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717

1818
package org.apache.spark.sql.catalyst.analysis
1919

20+
import java.sql.Timestamp
21+
2022
import org.apache.spark.sql.catalyst.plans.PlanTest
2123

2224
import org.apache.spark.sql.catalyst.expressions._
2325
import org.apache.spark.sql.catalyst.plans.logical._
2426
import org.apache.spark.sql.catalyst.rules.Rule
2527
import org.apache.spark.sql.types._
28+
import org.apache.spark.unsafe.types.CalendarInterval
2629

2730
class HiveTypeCoercionSuite extends PlanTest {
2831

@@ -400,6 +403,33 @@ class HiveTypeCoercionSuite extends PlanTest {
400403
}
401404
}
402405

406+
test("rule for date/timestamp operations") {
407+
val dateTimeOperations = HiveTypeCoercion.DateTimeOperations
408+
val date = Literal(new java.sql.Date(0L))
409+
val timestamp = Literal(new Timestamp(0L))
410+
val interval = Literal(new CalendarInterval(0, 0))
411+
val str = Literal("2015-01-01")
412+
413+
ruleTest(dateTimeOperations, Add(date, interval), Cast(TimeAdd(date, interval), DateType))
414+
ruleTest(dateTimeOperations, Add(interval, date), Cast(TimeAdd(date, interval), DateType))
415+
ruleTest(dateTimeOperations, Add(timestamp, interval),
416+
Cast(TimeAdd(timestamp, interval), TimestampType))
417+
ruleTest(dateTimeOperations, Add(interval, timestamp),
418+
Cast(TimeAdd(timestamp, interval), TimestampType))
419+
ruleTest(dateTimeOperations, Add(str, interval), Cast(TimeAdd(str, interval), StringType))
420+
ruleTest(dateTimeOperations, Add(interval, str), Cast(TimeAdd(str, interval), StringType))
421+
422+
ruleTest(dateTimeOperations, Subtract(date, interval), Cast(TimeSub(date, interval), DateType))
423+
ruleTest(dateTimeOperations, Subtract(timestamp, interval),
424+
Cast(TimeSub(timestamp, interval), TimestampType))
425+
ruleTest(dateTimeOperations, Subtract(str, interval), Cast(TimeSub(str, interval), StringType))
426+
427+
// interval operations should not be effected
428+
ruleTest(dateTimeOperations, Add(interval, interval), Add(interval, interval))
429+
ruleTest(dateTimeOperations, Subtract(interval, interval), Subtract(interval, interval))
430+
}
431+
432+
403433
/**
404434
* There are rules that need to not fire before child expressions get resolved.
405435
* We use this test to make sure those rules do not fire early.

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/DateExpressionsSuite.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import java.util.Calendar
2424
import org.apache.spark.SparkFunSuite
2525
import org.apache.spark.sql.catalyst.util.DateTimeUtils
2626
import org.apache.spark.sql.types.{StringType, TimestampType, DateType}
27-
import org.apache.spark.unsafe.types.Interval
27+
import org.apache.spark.unsafe.types.CalendarInterval
2828

2929
class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
3030

@@ -222,18 +222,20 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
222222

223223
test("time_add") {
224224
checkEvaluation(
225-
TimeAdd(Literal(Timestamp.valueOf("2016-01-29 10:00:00")), Literal(new Interval(1, 123000L))),
225+
TimeAdd(Literal(Timestamp.valueOf("2016-01-29 10:00:00")),
226+
Literal(new CalendarInterval(1, 123000L))),
226227
DateTimeUtils.fromJavaTimestamp(Timestamp.valueOf("2016-02-29 10:00:00.123")))
227228
}
228229

229230
test("time_sub") {
230231
checkEvaluation(
231-
TimeSub(Literal(Timestamp.valueOf("2016-03-31 10:00:00")), Literal(new Interval(1, 0))),
232+
TimeSub(Literal(Timestamp.valueOf("2016-03-31 10:00:00")),
233+
Literal(new CalendarInterval(1, 0))),
232234
DateTimeUtils.fromJavaTimestamp(Timestamp.valueOf("2016-02-29 10:00:00")))
233235
checkEvaluation(
234236
TimeSub(
235237
Literal(Timestamp.valueOf("2016-03-30 00:00:01")),
236-
Literal(new Interval(1, 2000000.toLong))),
238+
Literal(new CalendarInterval(1, 2000000.toLong))),
237239
DateTimeUtils.fromJavaTimestamp(Timestamp.valueOf("2016-02-28 23:59:59")))
238240
}
239241

sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import java.text.SimpleDateFormat
2222

2323
import org.apache.spark.sql.catalyst.util.DateTimeUtils
2424
import org.apache.spark.sql.functions._
25-
import org.apache.spark.unsafe.types.Interval
25+
import org.apache.spark.unsafe.types.CalendarInterval
2626

2727
class DateFunctionsSuite extends QueryTest {
2828
private lazy val ctx = org.apache.spark.sql.test.TestSQLContext
@@ -272,7 +272,7 @@ class DateFunctionsSuite extends QueryTest {
272272
val t2 = Timestamp.valueOf("2015-12-31 00:00:00")
273273
val d1 = Date.valueOf("2015-07-31")
274274
val d2 = Date.valueOf("2015-12-31")
275-
val i = new Interval(2, 2000000L)
275+
val i = new CalendarInterval(2, 2000000L)
276276
val df = Seq((1, t1, d1), (3, t2, d2)).toDF("n", "t", "d")
277277
checkAnswer(
278278
df.selectExpr(s"d + $i"),
@@ -288,7 +288,7 @@ class DateFunctionsSuite extends QueryTest {
288288
val t2 = Timestamp.valueOf("2016-02-29 00:00:02")
289289
val d1 = Date.valueOf("2015-09-30")
290290
val d2 = Date.valueOf("2016-02-29")
291-
val i = new Interval(2, 2000000L)
291+
val i = new CalendarInterval(2, 2000000L)
292292
val df = Seq((1, t1, d1), (3, t2, d2)).toDF("n", "t", "d")
293293
checkAnswer(
294294
df.selectExpr(s"d - $i"),

0 commit comments

Comments
 (0)