Skip to content

Commit 427d9dc

Browse files
committed
add tests and codegen
1 parent 0b69a1f commit 427d9dc

File tree

4 files changed

+118
-13
lines changed

4 files changed

+118
-13
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ object FunctionRegistry {
158158
expression[Substring]("substring"),
159159
expression[Upper]("ucase"),
160160
expression[UnHex]("unhex"),
161-
expression[Upper]("upper")
161+
expression[Upper]("upper"),
162+
163+
//datetime functions
164+
expression[CurrentDate]("current_date"),
165+
expression[CurrentTimestamp]("current_timestamp")
162166
)
163167

164168
val builtin: FunctionRegistry = {

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,52 @@
1717

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

20+
import org.apache.spark.sql.catalyst.expressions.codegen.{CodeGenContext, GeneratedExpressionCode}
2021
import org.apache.spark.sql.catalyst.util.DateTimeUtils
2122
import org.apache.spark.sql.types._
2223

2324
/**
24-
* Adds a number of days to startdate: date_add('2008-12-31', 1) = '2009-01-01'.
25+
* Returns the current date at the start of query evaluation.
26+
* All calls of current_date within the same query return the same value.
2527
*/
26-
case class CurrentTimestamp() extends Expression {
27-
override def children: Seq[Expression] = Nil
28-
28+
case class CurrentDate() extends LeafExpression {
2929
override def foldable: Boolean = true
3030
override def nullable: Boolean = false
3131

32-
override def dataType: DataType = TimestampType
32+
override def dataType: DataType = DateType
3333

3434
override def eval(input: InternalRow): Any = {
35-
(new java.util.Date()).getTime * 10000L
35+
DateTimeUtils.millisToDays(System.currentTimeMillis())
36+
}
37+
38+
override def genCode(ctx: CodeGenContext, ev: GeneratedExpressionCode): String = {
39+
val datetimeUtils = "org.apache.spark.sql.catalyst.util.DateTimeUtils"
40+
s"""
41+
boolean ${ev.isNull} = false;
42+
${ctx.javaType(dataType)} ${ev.primitive} =
43+
$datetimeUtils.millisToDays(System.currentTimeMillis());
44+
"""
3645
}
3746
}
3847

3948
/**
40-
* Subtracts a number of days to startdate: date_sub('2008-12-31', 1) = '2008-12-30'.
49+
* Returns the current timestamp at the start of query evaluation.
50+
* All calls of current_timestamp within the same query return the same value.
4151
*/
42-
case class CurrentDate() extends Expression {
43-
override def children: Seq[Expression] = Nil
44-
52+
case class CurrentTimestamp() extends LeafExpression {
4553
override def foldable: Boolean = true
4654
override def nullable: Boolean = false
4755

48-
override def dataType: DataType = DateType
56+
override def dataType: DataType = TimestampType
4957

5058
override def eval(input: InternalRow): Any = {
51-
DateTimeUtils.millisToDays((new java.util.Date()).getTime)
59+
System.currentTimeMillis() * 10000L
60+
}
61+
62+
override def genCode(ctx: CodeGenContext, ev: GeneratedExpressionCode): String = {
63+
s"""
64+
boolean ${ev.isNull} = false;
65+
${ctx.javaType(dataType)} ${ev.primitive} = System.currentTimeMillis() * 10000L;
66+
"""
5267
}
5368
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.spark.sql.catalyst.expressions
19+
20+
import java.sql.Date
21+
22+
import org.apache.spark.SparkFunSuite
23+
import org.apache.spark.sql.types.DateType
24+
25+
class DatetimeFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper {
26+
test("datetime function current_date") {
27+
checkEvaluation(
28+
CurrentDate(),
29+
new Date(System.currentTimeMillis), EmptyRow)
30+
}
31+
32+
test("datetime function current_timestamp") {
33+
// By the time we run check, current timestamp has been different.
34+
// So we just check the date part.
35+
checkEvaluation(
36+
Cast(CurrentTimestamp(), DateType),
37+
new Date(System.currentTimeMillis), EmptyRow)
38+
}
39+
40+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.spark.sql
19+
20+
import java.sql.Date
21+
22+
import org.apache.spark.sql.catalyst.util.DateTimeUtils
23+
import org.scalatest.BeforeAndAfterAll
24+
25+
class DatetimeExpressionsSuite extends QueryTest with BeforeAndAfterAll {
26+
private lazy val ctx = org.apache.spark.sql.test.TestSQLContext
27+
28+
test("function current_date") {
29+
// Date constructor would keep the original millis, we need to align it with begin of day.
30+
checkAnswer(ctx.sql("""SELECT CURRENT_DATE()"""),
31+
Row(new Date(DateTimeUtils.daysToMillis(
32+
DateTimeUtils.millisToDays(System.currentTimeMillis())))))
33+
}
34+
35+
test("function current_timestamp") {
36+
// Execution in one query should return the same value
37+
checkAnswer(ctx.sql("""SELECT CURRENT_TIMESTAMP() = CURRENT_TIMESTAMP()"""),
38+
Row(true))
39+
// By the time we run check, current timestamp has been different.
40+
// So we just check the date part.
41+
checkAnswer(ctx.sql("""SELECT CAST(CURRENT_TIMESTAMP() AS DATE)"""),
42+
Row(new Date(DateTimeUtils.daysToMillis(
43+
DateTimeUtils.millisToDays(System.currentTimeMillis())))))
44+
}
45+
46+
}

0 commit comments

Comments
 (0)