Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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 @@ -967,7 +967,6 @@ primaryExpression
| qualifiedName DOT ASTERISK #star
| LEFT_PAREN namedExpression (COMMA namedExpression)+ RIGHT_PAREN #rowConstructor
| LEFT_PAREN query RIGHT_PAREN #subqueryExpression
| IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN #identifierClause
| functionName LEFT_PAREN (setQuantifier? argument+=functionArgument
(COMMA argument+=functionArgument)*)? RIGHT_PAREN
(FILTER LEFT_PAREN WHERE where=booleanExpression RIGHT_PAREN)?
Expand Down Expand Up @@ -1196,6 +1195,7 @@ qualifiedNameList

functionName
: IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN
| identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name.
| qualifiedName
| FILTER
| LEFT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2246,13 +2246,6 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging {
}
}

/**
* Create an expression for the IDENTIFIER() clause.
*/
override def visitIdentifierClause(ctx: IdentifierClauseContext): Expression = withOrigin(ctx) {
ExpressionWithUnresolvedIdentifier(expression(ctx.expression), UnresolvedAttribute(_))
}

/**
* Create a (windowed) Function expression.
*/
Expand All @@ -2274,19 +2267,31 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging {
val filter = Option(ctx.where).map(expression(_))
val ignoreNulls =
Option(ctx.nullsOption).map(_.getType == SqlBaseParser.IGNORE).getOrElse(false)
val funcCtx = ctx.functionName
val func = withFuncIdentClause(
funcCtx,
ident => UnresolvedFunction(ident, arguments, isDistinct, filter, ignoreNulls)
)

// Check if the function is evaluated in a windowed context.
ctx.windowSpec match {
case spec: WindowRefContext =>
UnresolvedWindowExpression(func, visitWindowRef(spec))
case spec: WindowDefContext =>
WindowExpression(func, visitWindowDef(spec))
case _ => func
// Is this an IDENTIFIER clause instead of a function call?
if (ctx.functionName.identFunc != null &&
arguments.length == 1 && // One argument
ctx.setQuantifier == null && // No other clause
ctx.where == null &&
ctx.nullsOption == null &&
ctx.windowSpec == null) {
ExpressionWithUnresolvedIdentifier(arguments.head, UnresolvedAttribute(_))
} else {
// It's a function call
val funcCtx = ctx.functionName
val func = withFuncIdentClause(
funcCtx,
ident => UnresolvedFunction(ident, arguments, isDistinct, filter, ignoreNulls)
)

// Check if the function is evaluated in a windowed context.
ctx.windowSpec match {
case spec: WindowRefContext =>
UnresolvedWindowExpression(func, visitWindowRef(spec))
case spec: WindowDefContext =>
WindowExpression(func, visitWindowDef(spec))
case _ => func
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,11 @@ Project [coalesce(cast(null as int), 1) AS coalesce(NULL, 1)#x]


-- !query
SELECT IDENTIFIER('abs')(-1)
SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
-- !query analysis
Project [abs(-1) AS abs(-1)#x]
+- OneRowRelation
Project [abs(c1#x) AS abs(c1)#x]
+- SubqueryAlias T
+- LocalRelation [c1#x]


-- !query
Expand Down Expand Up @@ -708,6 +709,27 @@ org.apache.spark.sql.AnalysisException
}


-- !query
SELECT `IDENTIFIER`('abs')(c1) FROM VALUES(-1) AS T(c1)
-- !query analysis
org.apache.spark.sql.AnalysisException
{
"errorClass" : "UNRESOLVED_ROUTINE",
"sqlState" : "42883",
"messageParameters" : {
"routineName" : "`IDENTIFIER`",
"searchPath" : "[`system`.`builtin`, `system`.`session`, `spark_catalog`.`default`]"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 26,
"fragment" : "`IDENTIFIER`('abs')"
} ]
}


-- !query
CREATE TABLE IDENTIFIER(1)(c1 INT)
-- !query analysis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ DROP SCHEMA s;

-- Function reference
SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1);
SELECT IDENTIFIER('abs')(-1);
SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1);
SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1);

-- Table DDL
Expand Down Expand Up @@ -117,6 +117,7 @@ SELECT IDENTIFIER('') FROM VALUES(1) AS T(``);
VALUES(IDENTIFIER(CAST(NULL AS STRING)));
VALUES(IDENTIFIER(1));
VALUES(IDENTIFIER(SUBSTR('HELLO', 1, RAND() + 1)));
SELECT `IDENTIFIER`('abs')(c1) FROM VALUES(-1) AS T(c1);

CREATE TABLE IDENTIFIER(1)(c1 INT);
CREATE TABLE IDENTIFIER('a.b.c')(c1 INT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ struct<coalesce(NULL, 1):int>


-- !query
SELECT IDENTIFIER('abs')(-1)
SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
-- !query schema
struct<abs(-1):int>
struct<abs(c1):int>
-- !query output
1

Expand Down Expand Up @@ -818,6 +818,29 @@ org.apache.spark.sql.AnalysisException
}


-- !query
SELECT `IDENTIFIER`('abs')(c1) FROM VALUES(-1) AS T(c1)
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.AnalysisException
{
"errorClass" : "UNRESOLVED_ROUTINE",
"sqlState" : "42883",
"messageParameters" : {
"routineName" : "`IDENTIFIER`",
"searchPath" : "[`system`.`builtin`, `system`.`session`, `spark_catalog`.`default`]"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 26,
"fragment" : "`IDENTIFIER`('abs')"
} ]
}


-- !query
CREATE TABLE IDENTIFIER(1)(c1 INT)
-- !query schema
Expand Down