Skip to content

Commit d7a1787

Browse files
committed
Add timestamp tests
1 parent 9a9bd1a commit d7a1787

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/SpecialDatetimeValuesSuite.scala

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717

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

20-
import java.time.LocalDate
20+
import java.time.{Instant, LocalDate, LocalDateTime, LocalTime, ZoneId}
2121

2222
import org.apache.spark.sql.catalyst.dsl.plans._
2323
import org.apache.spark.sql.catalyst.expressions.{Alias, Cast, Literal}
2424
import org.apache.spark.sql.catalyst.plans.PlanTest
2525
import org.apache.spark.sql.catalyst.plans.logical.{LocalRelation, LogicalPlan, Project}
2626
import org.apache.spark.sql.catalyst.rules.RuleExecutor
27-
import org.apache.spark.sql.types.DateType
27+
import org.apache.spark.sql.catalyst.util.DateTimeConstants.MICROS_PER_MINUTE
28+
import org.apache.spark.sql.catalyst.util.DateTimeUtils.{instantToMicros, localDateTimeToMicros}
29+
import org.apache.spark.sql.types.{AtomicType, DateType, TimestampNTZType, TimestampType}
2830

2931
class SpecialDatetimeValuesSuite extends PlanTest {
3032
object Optimize extends RuleExecutor[LogicalPlan] {
@@ -55,4 +57,45 @@ class SpecialDatetimeValuesSuite extends PlanTest {
5557
assert(expected === lits.toSet)
5658
}
5759
}
60+
61+
private def testSpecialTs(tsType: AtomicType, expected: Set[Long], zoneId: ZoneId): Unit = {
62+
val in = Project(Seq(
63+
Alias(Cast(Literal("epoch"), tsType, Some(zoneId.getId)), "epoch")(),
64+
Alias(Cast(Literal("now"), tsType, Some(zoneId.getId)), "now")(),
65+
Alias(Cast(Literal("tomorrow"), tsType, Some(zoneId.getId)), "tomorrow")(),
66+
Alias(Cast(Literal("yesterday"), tsType, Some(zoneId.getId)), "yesterday")()),
67+
LocalRelation())
68+
69+
val plan = Optimize.execute(in.analyze).asInstanceOf[Project]
70+
val lits = new scala.collection.mutable.ArrayBuffer[Long]
71+
plan.transformAllExpressions { case e: Literal if e.dataType == tsType =>
72+
lits += e.value.asInstanceOf[Long]
73+
e
74+
}
75+
assert(lits.forall(ts => expected.exists(ets => Math.abs(ets -ts) <= MICROS_PER_MINUTE)))
76+
}
77+
78+
test("special timestamp_ltz values") {
79+
testSpecialDatetimeValues { zoneId =>
80+
val expected = Set(
81+
Instant.ofEpochSecond(0),
82+
Instant.now(),
83+
Instant.now().atZone(zoneId).`with`(LocalTime.MIDNIGHT).plusDays(1).toInstant,
84+
Instant.now().atZone(zoneId).`with`(LocalTime.MIDNIGHT).minusDays(1).toInstant
85+
).map(instantToMicros)
86+
testSpecialTs(TimestampType, expected, zoneId)
87+
}
88+
}
89+
90+
test("special timestamp_ntz values") {
91+
testSpecialDatetimeValues { zoneId =>
92+
val expected = Set(
93+
LocalDateTime.of(1970, 1, 1, 0, 0),
94+
LocalDateTime.now(),
95+
LocalDateTime.now().`with`(LocalTime.MIDNIGHT).plusDays(1),
96+
LocalDateTime.now().`with`(LocalTime.MIDNIGHT).minusDays(1)
97+
).map(localDateTimeToMicros)
98+
testSpecialTs(TimestampNTZType, expected, zoneId)
99+
}
100+
}
58101
}

0 commit comments

Comments
 (0)