aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g45
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala13
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala5
-rw-r--r--sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala11
4 files changed, 32 insertions, 2 deletions
diff --git a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
index 5e1046293a..c7d50869ea 100644
--- a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
+++ b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
@@ -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
: '\'' ( ~('\''|'\\') | ('\\' .) )* '\''
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index f2cc8d3624..679adf2717 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -1023,6 +1023,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.
*/
protected def visitFunctionName(ctx: QualifiedNameContext): FunctionIdentifier = {
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala
index e73592c7af..849d962128 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala
@@ -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())
+ }
}
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
index 6e485a8f5b..8e7c8d7f07 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
@@ -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)))
+ }
}