Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,7 @@ valueExpression
;

primaryExpression
: name=(CURRENT_DATE | CURRENT_TIMESTAMP) #timeFunctionCall
| CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase
: CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase
| CASE value=expression whenClause+ (ELSE elseExpression=expression)? END #simpleCase
| CAST '(' expression AS dataType ')' #cast
| STRUCT '(' (argument+=namedExpression (',' argument+=namedExpression)*)? ')' #struct
Expand Down Expand Up @@ -747,7 +746,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 | CURRENT_DATE | CURRENT_TIMESTAMP
| DATABASE | SELECT | FROM | WHERE | HAVING | TO | TABLE | WITH | NOT
| DIRECTORY
| BOTH | LEADING | TRAILING
;
Expand Down Expand Up @@ -983,8 +982,6 @@ OPTION: 'OPTION';
ANTI: 'ANTI';
LOCAL: 'LOCAL';
INPATH: 'INPATH';
CURRENT_DATE: 'CURRENT_DATE';
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';

STRING
: '\'' ( ~('\''|'\\') | ('\\' .) )* '\''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,25 @@ class Analyzer(
}
}

/**
* Literal functions do not require the user to specify braces when calling them
* When an attributes is not resolvable, we try to resolve it as a literal function.
*/
private def resolveAsLiteralFunctions(nameParts: Seq[String]): Option[NamedExpression] = {
if (nameParts.length != 1) {
return None
}
// support CURRENT_DATE and CURRENT_TIMESTAMP
val literalFunctions = Seq(CurrentDate(), CurrentTimestamp())
val name = nameParts.head
val func = literalFunctions.find(e => resolver(e.prettyName, name))
if (func.isDefined) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just map over the func option.

Some(Alias(func.get, toPrettySQL(func.get))())
} else {
None
}
}

def apply(plan: LogicalPlan): LogicalPlan = plan.resolveOperators {
case p: LogicalPlan if !p.childrenResolved => p

Expand Down Expand Up @@ -844,7 +863,12 @@ class Analyzer(
q.transformExpressionsUp {
case u @ UnresolvedAttribute(nameParts) =>
// Leave unchanged if resolution fails. Hopefully will be resolved next round.
val result = withPosition(u) { q.resolveChildren(nameParts, resolver).getOrElse(u) }
val result =
withPosition(u) {
q.resolveChildren(nameParts, resolver).getOrElse {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use orElse:
q.resolveChildren(nameParts, resolver).orElse(resolveAsLiteralFunctions(nameParts)).getOrElse(u)

resolveAsLiteralFunctions(nameParts).getOrElse(u)
}
}
logDebug(s"Resolving $u to $result")
result
case UnresolvedExtractValue(child, fieldExpr) if child.resolved =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1234,19 +1234,6 @@ class AstBuilder(conf: SQLConf) 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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-- !query 0
select current_date = current_date(), current_timestamp = current_timestamp()
-- !query 0 schema
struct<(current_date() = current_date()):boolean,(current_timestamp() = current_timestamp()):boolean>
struct<(current_date() AS `current_date()` = current_date()):boolean,(current_timestamp() AS `current_timestamp()` = current_timestamp()):boolean>
-- !query 0 output
true true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ class DateFunctionsSuite extends QueryTest with SharedSQLContext {
checkAnswer(sql("""SELECT CURRENT_TIMESTAMP() = NOW()"""), Row(true))
}

test("SPARK-22333: timeFunctionCall has conflicts with columnReference ") {
val df = Seq((1, 2), (2, 3)).toDF("current_date", "current_timestamp")
df.createOrReplaceTempView("ttf")
withTempView("ttf") {
checkAnswer(sql("SELECT current_date, current_timestamp FROM ttf"),
Seq(Row(1, 2), Row(2, 3)))
}

val df1 = Seq((1, 2), (2, 3)).toDF("a", "b")
df1.createOrReplaceTempView("ttf1")
withTempView("ttf1") {
checkAnswer(
sql("SELECT current_date = current_date(), current_timestamp = current_timestamp(), " +
"a, b FROM ttf1"),
Seq(Row(true, true, 1, 2), Row(true, true, 2, 3)))
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move these to datetime.sql?


val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
val sdfDate = new SimpleDateFormat("yyyy-MM-dd", Locale.US)
val d = new Date(sdf.parse("2015-04-08 13:10:15").getTime)
Expand Down