From 5c1878dd6771d6c7dc124f6319f5291056ee9031 Mon Sep 17 00:00:00 2001 From: srielau Date: Tue, 12 Sep 2023 10:22:36 +0200 Subject: [PATCH 1/7] [SPARK-45132] Fix IDENTIFIER for functions --- .../sql/catalyst/parser/SqlBaseParser.g4 | 1 - .../sql/catalyst/parser/AstBuilder.scala | 44 +++++++++++-------- .../identifier-clause.sql.out | 28 ++++++++++-- .../sql-tests/inputs/identifier-clause.sql | 3 +- .../results/identifier-clause.sql.out | 27 +++++++++++- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 6a6d39e96ca2..937e720af69b 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -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)? 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 f8a9ea268d2f..2cdbb825226a 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 @@ -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. */ @@ -2274,19 +2267,32 @@ 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 (name.toLowerCase(Locale.ROOT) == "identifier" && // IDENTIFIER (but not `IDENTIFIER`) + ctx.functionName().qualifiedName().start.getText.toLowerCase(Locale.ROOT) == "identifier" && + 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 + } } } diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out index 64268a75aced..a78039267643 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out @@ -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 @@ -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 diff --git a/sql/core/src/test/resources/sql-tests/inputs/identifier-clause.sql b/sql/core/src/test/resources/sql-tests/inputs/identifier-clause.sql index 00467244ff18..fd53f44d3c33 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/identifier-clause.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/identifier-clause.sql @@ -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 @@ -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); diff --git a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out index cfedaae39e81..d8ac69dd120f 100644 --- a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out @@ -205,9 +205,9 @@ struct -- !query -SELECT IDENTIFIER('abs')(-1) +SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1) -- !query schema -struct +struct -- !query output 1 @@ -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 From 3c8fb1586c79079ee6b2aa1a6dc8c4e88015dd3f Mon Sep 17 00:00:00 2001 From: srielau Date: Mon, 9 Oct 2023 21:12:56 -0700 Subject: [PATCH 2/7] Attempt rework --- .../sql/catalyst/parser/SqlBaseParser.g4 | 2 +- .../sql/catalyst/parser/AstBuilder.scala | 20 ++++++------ .../identifier-clause.sql.out | 30 +++++++++++++++--- .../results/identifier-clause.sql.out | 31 ++++++++++++++++--- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 937e720af69b..8d74e8619f77 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -967,7 +967,7 @@ primaryExpression | qualifiedName DOT ASTERISK #star | LEFT_PAREN namedExpression (COMMA namedExpression)+ RIGHT_PAREN #rowConstructor | LEFT_PAREN query RIGHT_PAREN #subqueryExpression - | functionName LEFT_PAREN (setQuantifier? argument+=functionArgument + | ( IDENTIFIER_KW | functionName ) LEFT_PAREN (setQuantifier? argument+=functionArgument (COMMA argument+=functionArgument)*)? RIGHT_PAREN (FILTER LEFT_PAREN WHERE where=booleanExpression RIGHT_PAREN)? (nullsOption=(IGNORE | RESPECT) NULLS)? ( OVER windowSpec)? #functionCall 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 d8333a79081d..4374803e4a69 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 @@ -2251,7 +2251,7 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging { */ override def visitFunctionCall(ctx: FunctionCallContext): Expression = withOrigin(ctx) { // Create the function call. - val name = ctx.functionName.getText + val name = if (ctx.IDENTIFIER_KW() != null) { "IDENTIFIER" } else { ctx.functionName.getText } val isDistinct = Option(ctx.setQuantifier()).exists(_.DISTINCT != null) // Call `toSeq`, otherwise `ctx.argument.asScala.map(expression)` is `Buffer` in Scala 2.13 val arguments = ctx.argument.asScala.map { e => @@ -2269,14 +2269,16 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging { Option(ctx.nullsOption).map(_.getType == SqlBaseParser.IGNORE).getOrElse(false) // Is this an IDENTIFIER clause instead of a function call? - if (name.toLowerCase(Locale.ROOT) == "identifier" && // IDENTIFIER (but not `IDENTIFIER`) - ctx.functionName().qualifiedName().start.getText.toLowerCase(Locale.ROOT) == "identifier" && - arguments.length == 1 && // One argument - ctx.setQuantifier == null && // No other clause - ctx.where == null && - ctx.nullsOption == null && - ctx.windowSpec == null) { - ExpressionWithUnresolvedIdentifier(arguments.head, UnresolvedAttribute(_)) + if (ctx.IDENTIFIER_KW() != null) { + if (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 { + UnresolvedFunction(Seq("identifier"), arguments, isDistinct, filter, ignoreNulls) + } } else { // It's a function call val funcCtx = ctx.functionName diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out index a78039267643..654074cb9be7 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out @@ -182,16 +182,36 @@ DropNamespace false, false -- !query SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1) -- !query analysis -Project [coalesce(cast(null as int), 1) AS coalesce(NULL, 1)#x] -+- OneRowRelation +org.apache.spark.sql.catalyst.parser.ParseException +{ + "errorClass" : "PARSE_SYNTAX_ERROR", + "sqlState" : "42601", + "messageParameters" : { + "error" : "'1'", + "hint" : "" + } +} -- !query SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1) -- !query analysis -Project [abs(c1#x) AS abs(c1)#x] -+- SubqueryAlias T - +- LocalRelation [c1#x] +org.apache.spark.sql.catalyst.ExtendedAnalysisException +{ + "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION", + "sqlState" : "42703", + "messageParameters" : { + "objectName" : "`abs`", + "proposal" : "`c1`" + }, + "queryContext" : [ { + "objectType" : "", + "objectName" : "", + "startIndex" : 8, + "stopIndex" : 24, + "fragment" : "IDENTIFIER('abs')" + } ] +} -- !query diff --git a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out index d8ac69dd120f..7fde502e0b80 100644 --- a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out @@ -199,17 +199,40 @@ struct<> -- !query SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1) -- !query schema -struct +struct<> -- !query output -1 +org.apache.spark.sql.catalyst.parser.ParseException +{ + "errorClass" : "PARSE_SYNTAX_ERROR", + "sqlState" : "42601", + "messageParameters" : { + "error" : "'1'", + "hint" : "" + } +} -- !query SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1) -- !query schema -struct +struct<> -- !query output -1 +org.apache.spark.sql.catalyst.ExtendedAnalysisException +{ + "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION", + "sqlState" : "42703", + "messageParameters" : { + "objectName" : "`abs`", + "proposal" : "`c1`" + }, + "queryContext" : [ { + "objectType" : "", + "objectName" : "", + "startIndex" : 8, + "stopIndex" : 24, + "fragment" : "IDENTIFIER('abs')" + } ] +} -- !query From c7ef299cde3d3af8c6a16132d1e2f16608758ded Mon Sep 17 00:00:00 2001 From: srielau Date: Mon, 9 Oct 2023 21:13:34 -0700 Subject: [PATCH 3/7] Revert "Attempt rework" This reverts commit 3c8fb1586c79079ee6b2aa1a6dc8c4e88015dd3f. --- .../sql/catalyst/parser/SqlBaseParser.g4 | 2 +- .../sql/catalyst/parser/AstBuilder.scala | 20 ++++++------ .../identifier-clause.sql.out | 30 +++--------------- .../results/identifier-clause.sql.out | 31 +++---------------- 4 files changed, 19 insertions(+), 64 deletions(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 8d74e8619f77..937e720af69b 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -967,7 +967,7 @@ primaryExpression | qualifiedName DOT ASTERISK #star | LEFT_PAREN namedExpression (COMMA namedExpression)+ RIGHT_PAREN #rowConstructor | LEFT_PAREN query RIGHT_PAREN #subqueryExpression - | ( IDENTIFIER_KW | functionName ) LEFT_PAREN (setQuantifier? argument+=functionArgument + | functionName LEFT_PAREN (setQuantifier? argument+=functionArgument (COMMA argument+=functionArgument)*)? RIGHT_PAREN (FILTER LEFT_PAREN WHERE where=booleanExpression RIGHT_PAREN)? (nullsOption=(IGNORE | RESPECT) NULLS)? ( OVER windowSpec)? #functionCall 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 4374803e4a69..d8333a79081d 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 @@ -2251,7 +2251,7 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging { */ override def visitFunctionCall(ctx: FunctionCallContext): Expression = withOrigin(ctx) { // Create the function call. - val name = if (ctx.IDENTIFIER_KW() != null) { "IDENTIFIER" } else { ctx.functionName.getText } + val name = ctx.functionName.getText val isDistinct = Option(ctx.setQuantifier()).exists(_.DISTINCT != null) // Call `toSeq`, otherwise `ctx.argument.asScala.map(expression)` is `Buffer` in Scala 2.13 val arguments = ctx.argument.asScala.map { e => @@ -2269,16 +2269,14 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging { Option(ctx.nullsOption).map(_.getType == SqlBaseParser.IGNORE).getOrElse(false) // Is this an IDENTIFIER clause instead of a function call? - if (ctx.IDENTIFIER_KW() != null) { - if (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 { - UnresolvedFunction(Seq("identifier"), arguments, isDistinct, filter, ignoreNulls) - } + if (name.toLowerCase(Locale.ROOT) == "identifier" && // IDENTIFIER (but not `IDENTIFIER`) + ctx.functionName().qualifiedName().start.getText.toLowerCase(Locale.ROOT) == "identifier" && + 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 diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out index 654074cb9be7..a78039267643 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause.sql.out @@ -182,36 +182,16 @@ DropNamespace false, false -- !query SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1) -- !query analysis -org.apache.spark.sql.catalyst.parser.ParseException -{ - "errorClass" : "PARSE_SYNTAX_ERROR", - "sqlState" : "42601", - "messageParameters" : { - "error" : "'1'", - "hint" : "" - } -} +Project [coalesce(cast(null as int), 1) AS coalesce(NULL, 1)#x] ++- OneRowRelation -- !query SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1) -- !query analysis -org.apache.spark.sql.catalyst.ExtendedAnalysisException -{ - "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION", - "sqlState" : "42703", - "messageParameters" : { - "objectName" : "`abs`", - "proposal" : "`c1`" - }, - "queryContext" : [ { - "objectType" : "", - "objectName" : "", - "startIndex" : 8, - "stopIndex" : 24, - "fragment" : "IDENTIFIER('abs')" - } ] -} +Project [abs(c1#x) AS abs(c1)#x] ++- SubqueryAlias T + +- LocalRelation [c1#x] -- !query diff --git a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out index 7fde502e0b80..d8ac69dd120f 100644 --- a/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/identifier-clause.sql.out @@ -199,40 +199,17 @@ struct<> -- !query SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1) -- !query schema -struct<> +struct -- !query output -org.apache.spark.sql.catalyst.parser.ParseException -{ - "errorClass" : "PARSE_SYNTAX_ERROR", - "sqlState" : "42601", - "messageParameters" : { - "error" : "'1'", - "hint" : "" - } -} +1 -- !query SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1) -- !query schema -struct<> +struct -- !query output -org.apache.spark.sql.catalyst.ExtendedAnalysisException -{ - "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION", - "sqlState" : "42703", - "messageParameters" : { - "objectName" : "`abs`", - "proposal" : "`c1`" - }, - "queryContext" : [ { - "objectType" : "", - "objectName" : "", - "startIndex" : 8, - "stopIndex" : 24, - "fragment" : "IDENTIFIER('abs')" - } ] -} +1 -- !query From a78bbcb48cdeea3ccaa47e1c71ab9acd4035a3d9 Mon Sep 17 00:00:00 2001 From: Wenchen Fan Date: Wed, 11 Oct 2023 14:59:28 +0800 Subject: [PATCH 4/7] improve --- .../org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 | 1 + .../org/apache/spark/sql/catalyst/parser/AstBuilder.scala | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 937e720af69b..09c01845c1d2 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -1195,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 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 d8333a79081d..9abca8b95cf7 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 @@ -2269,8 +2269,7 @@ class AstBuilder extends DataTypeAstBuilder with SQLConfHelper with Logging { Option(ctx.nullsOption).map(_.getType == SqlBaseParser.IGNORE).getOrElse(false) // Is this an IDENTIFIER clause instead of a function call? - if (name.toLowerCase(Locale.ROOT) == "identifier" && // IDENTIFIER (but not `IDENTIFIER`) - ctx.functionName().qualifiedName().start.getText.toLowerCase(Locale.ROOT) == "identifier" && + if (ctx.functionName.identFunc != null && arguments.length == 1 && // One argument ctx.setQuantifier == null && // No other clause ctx.where == null && From dca9ec31e935490e847577f5ddc136c8093268db Mon Sep 17 00:00:00 2001 From: Wenchen Fan Date: Wed, 11 Oct 2023 04:04:58 -0700 Subject: [PATCH 5/7] Update sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 --- .../org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 09c01845c1d2..77a9108e0632 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -1195,7 +1195,7 @@ qualifiedNameList functionName : IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN - | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. + | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. | qualifiedName | FILTER | LEFT From ab4c09414b580a898c42136328782c66ba04cef2 Mon Sep 17 00:00:00 2001 From: Wenchen Fan Date: Wed, 11 Oct 2023 20:55:24 -0700 Subject: [PATCH 6/7] Update sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 --- .../org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 77a9108e0632..09c01845c1d2 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -1195,7 +1195,7 @@ qualifiedNameList functionName : IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN - | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. + | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. | qualifiedName | FILTER | LEFT From 75c746bcc14e3d6cac65c6b06877314f6cc34867 Mon Sep 17 00:00:00 2001 From: Wenchen Fan Date: Thu, 12 Oct 2023 00:21:35 -0700 Subject: [PATCH 7/7] Update sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 --- .../org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 index 09c01845c1d2..77a9108e0632 100644 --- a/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 +++ b/sql/api/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 @@ -1195,7 +1195,7 @@ qualifiedNameList functionName : IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN - | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. + | identFunc=IDENTIFIER_KW // IDENTIFIER itself is also a valid function name. | qualifiedName | FILTER | LEFT