Skip to content
Snippets Groups Projects
Commit 2330f3ec authored by Herman van Hovell's avatar Herman van Hovell Committed by Reynold Xin
Browse files

[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 <hvanhovell@databricks.com>

Closes #14442 from hvanhovell/SPARK-16836.
parent 146001a9
No related branches found
No related tags found
No related merge requests found
......@@ -500,6 +500,7 @@ valueExpression
primaryExpression
: constant #constantDefault
| name=(CURRENT_DATE | CURRENT_TIMESTAMP) #timeFunctionCall
| ASTERISK #star
| qualifiedName '.' ASTERISK #star
| '(' expression (',' expression)+ ')' #rowConstructor
......@@ -660,7 +661,7 @@ nonReserved
| NULL | ORDER | OUTER | TABLE | TRUE | WITH | RLIKE
| AND | CASE | CAST | DISTINCT | DIV | ELSE | END | FUNCTION | INTERVAL | MACRO | OR | STRATIFY | THEN
| UNBOUNDED | WHEN
| DATABASE | SELECT | FROM | WHERE | HAVING | TO | TABLE | WITH | NOT
| DATABASE | SELECT | FROM | WHERE | HAVING | TO | TABLE | WITH | NOT | CURRENT_DATE | CURRENT_TIMESTAMP
;
SELECT: 'SELECT';
......@@ -880,6 +881,8 @@ OPTION: 'OPTION';
ANTI: 'ANTI';
LOCAL: 'LOCAL';
INPATH: 'INPATH';
CURRENT_DATE: 'CURRENT_DATE';
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';
STRING
: '\'' ( ~('\''|'\\') | ('\\' .) )* '\''
......
......@@ -1022,6 +1022,19 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
}
}
/**
* Create a current timestamp/date expression. These are different from regular function because
* they do not require the user to specify braces when calling them.
*/
override def visitTimeFunctionCall(ctx: TimeFunctionCallContext): Expression = withOrigin(ctx) {
ctx.name.getType match {
case SqlBaseParser.CURRENT_DATE =>
CurrentDate()
case SqlBaseParser.CURRENT_TIMESTAMP =>
CurrentTimestamp()
}
}
/**
* Create a function database (optional) and name pair.
*/
......
......@@ -502,4 +502,9 @@ class ExpressionParserSuite extends PlanTest {
assertEqual("1 - f('o', o(bar))", Literal(1) - 'f.function("o", 'o.function('bar)))
intercept("1 - f('o', o(bar)) hello * world", "mismatched input '*'")
}
test("current date/timestamp braceless expressions") {
assertEqual("current_date", CurrentDate())
assertEqual("current_timestamp", CurrentTimestamp())
}
}
......@@ -18,7 +18,7 @@
package org.apache.spark.sql
import java.math.MathContext
import java.sql.Timestamp
import java.sql.{Date, Timestamp}
import org.apache.spark.{AccumulatorSuite, SparkException}
import org.apache.spark.sql.catalyst.analysis.UnresolvedException
......@@ -3017,4 +3017,13 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
data.selectExpr("`part.col1`", "`col.1`"))
}
}
test("current_date and current_timestamp literals") {
// NOTE that I am comparing the result of the literal with the result of the function call.
// This is done to prevent the test from failing because we are comparing a result to an out
// dated timestamp (quite likely) or date (very unlikely - but equally annoying).
checkAnswer(
sql("select current_date = current_date(), current_timestamp = current_timestamp()"),
Seq(Row(true, true)))
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment