Skip to content

Commit a937c9e

Browse files
hvanhovellrxin
authored andcommitted
[SPARK-16836][SQL] Add support for CURRENT_DATE/CURRENT_TIMESTAMP literals
## What changes were proposed in this pull request? In Spark 1.6 (with Hive support) we could use `CURRENT_DATE` and `CURRENT_TIMESTAMP` functions as literals (without adding braces), for example: ```SQL select /* Spark 1.6: */ current_date, /* Spark 1.6 & Spark 2.0: */ current_date() ``` This was accidentally dropped in Spark 2.0. This PR reinstates this functionality. ## How was this patch tested? Added a case to ExpressionParserSuite. Author: Herman van Hovell <[email protected]> Closes #14442 from hvanhovell/SPARK-16836. (cherry picked from commit 2330f3e) Signed-off-by: Reynold Xin <[email protected]>
1 parent ef7927e commit a937c9e

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ valueExpression
493493

494494
primaryExpression
495495
: constant #constantDefault
496+
| name=(CURRENT_DATE | CURRENT_TIMESTAMP) #timeFunctionCall
496497
| ASTERISK #star
497498
| qualifiedName '.' ASTERISK #star
498499
| '(' expression (',' expression)+ ')' #rowConstructor
@@ -653,7 +654,7 @@ nonReserved
653654
| NULL | ORDER | OUTER | TABLE | TRUE | WITH | RLIKE
654655
| AND | CASE | CAST | DISTINCT | DIV | ELSE | END | FUNCTION | INTERVAL | MACRO | OR | STRATIFY | THEN
655656
| UNBOUNDED | WHEN
656-
| DATABASE | SELECT | FROM | WHERE | HAVING | TO | TABLE | WITH | NOT
657+
| DATABASE | SELECT | FROM | WHERE | HAVING | TO | TABLE | WITH | NOT | CURRENT_DATE | CURRENT_TIMESTAMP
657658
;
658659

659660
SELECT: 'SELECT';
@@ -873,6 +874,8 @@ OPTION: 'OPTION';
873874
ANTI: 'ANTI';
874875
LOCAL: 'LOCAL';
875876
INPATH: 'INPATH';
877+
CURRENT_DATE: 'CURRENT_DATE';
878+
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';
876879

877880
STRING
878881
: '\'' ( ~('\''|'\\') | ('\\' .) )* '\''

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,19 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
10221022
}
10231023
}
10241024

1025+
/**
1026+
* Create a current timestamp/date expression. These are different from regular function because
1027+
* they do not require the user to specify braces when calling them.
1028+
*/
1029+
override def visitTimeFunctionCall(ctx: TimeFunctionCallContext): Expression = withOrigin(ctx) {
1030+
ctx.name.getType match {
1031+
case SqlBaseParser.CURRENT_DATE =>
1032+
CurrentDate()
1033+
case SqlBaseParser.CURRENT_TIMESTAMP =>
1034+
CurrentTimestamp()
1035+
}
1036+
}
1037+
10251038
/**
10261039
* Create a function database (optional) and name pair.
10271040
*/

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,9 @@ class ExpressionParserSuite extends PlanTest {
502502
assertEqual("1 - f('o', o(bar))", Literal(1) - 'f.function("o", 'o.function('bar)))
503503
intercept("1 - f('o', o(bar)) hello * world", "mismatched input '*'")
504504
}
505+
506+
test("current date/timestamp braceless expressions") {
507+
assertEqual("current_date", CurrentDate())
508+
assertEqual("current_timestamp", CurrentTimestamp())
509+
}
505510
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
package org.apache.spark.sql
1919

2020
import java.math.MathContext
21-
import java.sql.Timestamp
21+
import java.sql.{Date, Timestamp}
2222

2323
import org.apache.spark.{AccumulatorSuite, SparkException}
2424
import org.apache.spark.sql.catalyst.analysis.UnresolvedException
@@ -2981,4 +2981,13 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
29812981
data.selectExpr("`part.col1`", "`col.1`"))
29822982
}
29832983
}
2984+
2985+
test("current_date and current_timestamp literals") {
2986+
// NOTE that I am comparing the result of the literal with the result of the function call.
2987+
// This is done to prevent the test from failing because we are comparing a result to an out
2988+
// dated timestamp (quite likely) or date (very unlikely - but equally annoying).
2989+
checkAnswer(
2990+
sql("select current_date = current_date(), current_timestamp = current_timestamp()"),
2991+
Seq(Row(true, true)))
2992+
}
29842993
}

0 commit comments

Comments
 (0)