You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ur...@apache.org on 2026/08/27 15:08:27 UTC

(spark) branch branch-4.x updated: [SPARK-58641][SQL][TEST] Add identifier clause function resolution tests

This is an automated email from the ASF dual-hosted git repository.

uros-b pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new b9e9644d79f6 [SPARK-58641][SQL][TEST] Add identifier clause function resolution tests
b9e9644d79f6 is described below

commit b9e9644d79f6b9768468f0314e65de7603d3b75f
Author: Vladan Vasić <vl...@databricks.com>
AuthorDate: Thu Aug 27 15:08:04 2026 +0000

    [SPARK-58641][SQL][TEST] Add identifier clause function resolution tests
    
    ### What changes were proposed in this pull request?
    
    This is a test-only PR for SPARK-58641. It adds SQL coverage and regenerated golden files without changing production code.
    
    Expand the `identifier-clause` SQL tests to cover identifier names computed through standard function resolution, including built-in and higher-order functions, aggregate/window/generator expressions, SQL functions and their dependencies, relation identifiers, and scalar subqueries.
    
    Regenerate the standard and legacy analyzer and execution golden files.
    
    ### Why are the changes needed?
    
    These cases provide coverage for function resolution while computing `IDENTIFIER` names and keep the shared identifier golden files synchronized across Spark analyzer implementations.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. This is a test-only change.
    
    ### How was this patch tested?
    
    - Regenerated the standard and legacy analyzer and execution golden files.
    - Ran `./build/sbt "sql/testOnly org.apache.spark.sql.SQLQueryTestSuite -- -z identifier-clause"`.
    - All 4 matching tests passed.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: OpenAI Codex (GPT-5)
    
    Closes #57850 from vladanvasi-db/effort/identifier-spark.
    
    Authored-by: Vladan Vasić <vl...@databricks.com>
    Signed-off-by: Uros Bojanic <22...@users.noreply.github.com>
    (cherry picked from commit ef34791d42891a4e42ed50b3ef04664dee801bdd)
    Signed-off-by: Uros Bojanic <22...@users.noreply.github.com>
---
 .../identifier-clause-legacy.sql.out               | 557 ++++++++++++++++
 .../analyzer-results/identifier-clause.sql.out     | 557 ++++++++++++++++
 .../sql-tests/inputs/identifier-clause.sql         |  72 ++
 .../results/identifier-clause-legacy.sql.out       | 733 +++++++++++++++++++--
 .../sql-tests/results/identifier-clause.sql.out    | 733 +++++++++++++++++++--
 5 files changed, 2548 insertions(+), 104 deletions(-)

diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause-legacy.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause-legacy.sql.out
index 6164ff65dabc..24f34afc6f09 100644
--- a/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause-legacy.sql.out
+++ b/sql/core/src/test/resources/sql-tests/analyzer-results/identifier-clause-legacy.sql.out
@@ -61,6 +61,14 @@ Project [c1#x]
    +- LocalRelation [c1#x]
 
 
+-- !query
+SELECT IDENTIFIER(concat('a', 'b')) FROM VALUES(1) AS T(ab)
+-- !query analysis
+Project [ab#x]
++- SubqueryAlias T
+   +- LocalRelation [ab#x]
+
+
 -- !query
 CREATE SCHEMA IF NOT EXISTS s
 -- !query analysis
@@ -163,6 +171,14 @@ Project [c1#x]
    +- Relation spark_catalog.s.tab[c1#x] csv
 
 
+-- !query
+SELECT * FROM IDENTIFIER(concat('t', 'ab'))
+-- !query analysis
+Project [c1#x]
++- SubqueryAlias spark_catalog.s.tab
+   +- Relation spark_catalog.s.tab[c1#x] csv
+
+
 -- !query
 USE SCHEMA default
 -- !query analysis
@@ -190,6 +206,13 @@ Project [coalesce(cast(null as int), 1) AS coalesce(NULL, 1)#x]
 +- OneRowRelation
 
 
+-- !query
+SELECT IDENTIFIER(concat('COAL', 'ESCE'))(NULL, 1)
+-- !query analysis
+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
@@ -205,6 +228,483 @@ Project [id#xL]
 +- Range (0, 1, step=1)
 
 
+-- !query
+VALUES(IDENTIFIER(abs(1)))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.WRONG_TYPE",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "dataType" : "int",
+    "expr" : "abs(1)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "abs(1)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(nullif('a', 'a'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "nullif('a', 'a')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 41,
+    "fragment" : "nullif('a', 'a')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(max('c1')) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('c1')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 27,
+    "fragment" : "max('c1')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(array_join(transform(array('c', '1'), element -> element), ''))
+FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('c', '1'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 80,
+    "fragment" : "array_join(transform(array('c', '1'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(rand()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "rand()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "rand()"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER ()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "wf_expr" : "row_number()",
+    "wf_name" : "row_number"
+  }
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER (ORDER BY 'x')) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 50,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(explode(array('c1'))) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "explode(array('c1'))",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 38,
+    "fragment" : "explode(array('c1'))"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(max('identifier_function_table'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('identifier_function_table')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "max('identifier_function_table')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(row_number() OVER (ORDER BY 'x'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  array_join(transform(array('identifier', '_function_table'), element -> element), '')
+)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('identifier', '_function_table'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 113,
+    "fragment" : "array_join(transform(array('identifier', '_function_table'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand identifier_name, STRING, 'c1', false, true, false, false
+
+
+-- !query
+SELECT IDENTIFIER(identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 35,
+    "fragment" : "identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_name
+-- !query analysis
+DropFunctionCommand identifier_name, false, true
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_name, STRING, 'c1', false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 46,
+    "fragment" : "persistent_identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_name, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_function(value INT)
+RETURNS INT
+RETURN value + 1
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_function, value INT, INT, value + 1, false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(concat('persistent_identifier_', 'function'))(1)
+-- !query analysis
+Project [spark_catalog.default.persistent_identifier_function(value#x) AS spark_catalog.default.persistent_identifier_function(1)#x]
++- Project [cast(1 as int) AS value#x]
+   +- OneRowRelation
+
+
+-- !query
+DROP FUNCTION persistent_identifier_function
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_function, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_base_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_base_name, STRING, 'c1', false, false, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_nested_name()
+RETURNS STRING
+RETURN persistent_identifier_base_name()
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_nested_name, STRING, persistent_identifier_base_name(), false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_nested_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_nested_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 53,
+    "fragment" : "persistent_identifier_nested_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_nested_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_nested_name, false, false
+
+
+-- !query
+DROP FUNCTION persistent_identifier_base_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_base_name, false, false
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
+-- !query analysis
+CreateSQLFunctionCommand identifier_relation_name, STRING, 'identifier_function_table', false, true, false, false
+
+
+-- !query
+CREATE TABLE identifier_function_table(c1 INT) USING csv
+-- !query analysis
+CreateDataSourceTableCommand `spark_catalog`.`default`.`identifier_function_table`, false
+
+
+-- !query
+SELECT * FROM IDENTIFIER(identifier_relation_name())
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 51,
+    "fragment" : "identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_count()
+RETURNS BIGINT
+RETURN SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table'))
+-- !query analysis
+CreateSQLFunctionCommand identifier_relation_count, BIGINT, SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table')), false, true, false, false
+
+
+-- !query
+SELECT identifier_relation_count()
+-- !query analysis
+Project [identifier_relation_count() AS identifier_relation_count()#xL]
+:  +- Aggregate [count(1) AS count(1)#xL]
+:     +- SubqueryAlias spark_catalog.default.identifier_function_table
+:        +- Relation spark_catalog.default.identifier_function_table[c1#x] csv
++- Project
+   +- OneRowRelation
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_count
+-- !query analysis
+DropFunctionCommand identifier_relation_count, false, true
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_relation_name, STRING, 'identifier_function_table', false, false, false, false
+
+
+-- !query
+SELECT * FROM IDENTIFIER(persistent_identifier_relation_name())
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 62,
+    "fragment" : "persistent_identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_relation_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_relation_name, false, false
+
+
+-- !query
+DROP TABLE identifier_function_table
+-- !query analysis
+DropTable false, false
++- ResolvedIdentifier V2SessionCatalog(spark_catalog), default.identifier_function_table
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_name
+-- !query analysis
+DropFunctionCommand identifier_relation_name, false, true
+
+
 -- !query
 CREATE TABLE IDENTIFIER('tab')(c1 INT) USING CSV
 -- !query analysis
@@ -743,6 +1243,12 @@ CREATE TABLE t(col1 INT)
 CreateDataSourceTableCommand `spark_catalog`.`default`.`t`, false
 
 
+-- !query
+CREATE TABLE identifier_name_source(name STRING) USING csv
+-- !query analysis
+CreateDataSourceTableCommand `spark_catalog`.`default`.`identifier_name_source`, false
+
+
 -- !query
 SELECT * FROM IDENTIFIER((SELECT 't'))
 -- !query analysis
@@ -764,6 +1270,50 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 }
 
 
+-- !query
+SELECT * FROM IDENTIFIER((SELECT max(name) FROM identifier_name_source))
+-- !query analysis
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 71,
+    "fragment" : "(SELECT max(name) FROM identifier_name_source)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  (SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)
+)
+-- !query analysis
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 84,
+    "fragment" : "(SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)"
+  } ]
+}
+
+
 -- !query
 SELECT * FROM (SELECT IDENTIFIER((SELECT 'col1')) FROM IDENTIFIER((SELECT 't')))
 -- !query analysis
@@ -848,6 +1398,13 @@ org.apache.spark.sql.catalyst.parser.ParseException
 }
 
 
+-- !query
+DROP TABLE identifier_name_source
+-- !query analysis
+DropTable false, false
++- ResolvedIdentifier V2SessionCatalog(spark_catalog), default.identifier_name_source
+
+
 -- !query
 DROP TABLE t
 -- !query analysis
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 35ceffe4ac9f..31df29577793 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
@@ -61,6 +61,14 @@ Project [c1#x]
    +- LocalRelation [c1#x]
 
 
+-- !query
+SELECT IDENTIFIER(concat('a', 'b')) FROM VALUES(1) AS T(ab)
+-- !query analysis
+Project [ab#x]
++- SubqueryAlias T
+   +- LocalRelation [ab#x]
+
+
 -- !query
 CREATE SCHEMA IF NOT EXISTS s
 -- !query analysis
@@ -163,6 +171,14 @@ Project [c1#x]
    +- Relation spark_catalog.s.tab[c1#x] csv
 
 
+-- !query
+SELECT * FROM IDENTIFIER(concat('t', 'ab'))
+-- !query analysis
+Project [c1#x]
++- SubqueryAlias spark_catalog.s.tab
+   +- Relation spark_catalog.s.tab[c1#x] csv
+
+
 -- !query
 USE SCHEMA default
 -- !query analysis
@@ -190,6 +206,13 @@ Project [coalesce(cast(null as int), 1) AS coalesce(NULL, 1)#x]
 +- OneRowRelation
 
 
+-- !query
+SELECT IDENTIFIER(concat('COAL', 'ESCE'))(NULL, 1)
+-- !query analysis
+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
@@ -205,6 +228,483 @@ Project [id#xL]
 +- Range (0, 1, step=1)
 
 
+-- !query
+VALUES(IDENTIFIER(abs(1)))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.WRONG_TYPE",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "dataType" : "int",
+    "expr" : "abs(1)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "abs(1)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(nullif('a', 'a'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "nullif('a', 'a')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 41,
+    "fragment" : "nullif('a', 'a')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(max('c1')) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('c1')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 27,
+    "fragment" : "max('c1')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(array_join(transform(array('c', '1'), element -> element), ''))
+FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('c', '1'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 80,
+    "fragment" : "array_join(transform(array('c', '1'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(rand()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "rand()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "rand()"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER ()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "wf_expr" : "row_number()",
+    "wf_name" : "row_number"
+  }
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER (ORDER BY 'x')) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 50,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(explode(array('c1'))) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "explode(array('c1'))",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 38,
+    "fragment" : "explode(array('c1'))"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(max('identifier_function_table'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('identifier_function_table')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "max('identifier_function_table')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(row_number() OVER (ORDER BY 'x'))
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  array_join(transform(array('identifier', '_function_table'), element -> element), '')
+)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('identifier', '_function_table'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 113,
+    "fragment" : "array_join(transform(array('identifier', '_function_table'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand identifier_name, STRING, 'c1', false, true, false, false
+
+
+-- !query
+SELECT IDENTIFIER(identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 35,
+    "fragment" : "identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_name
+-- !query analysis
+DropFunctionCommand identifier_name, false, true
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_name, STRING, 'c1', false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 46,
+    "fragment" : "persistent_identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_name, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_function(value INT)
+RETURNS INT
+RETURN value + 1
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_function, value INT, INT, value + 1, false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(concat('persistent_identifier_', 'function'))(1)
+-- !query analysis
+Project [spark_catalog.default.persistent_identifier_function(value#x) AS spark_catalog.default.persistent_identifier_function(1)#x]
++- Project [cast(1 as int) AS value#x]
+   +- OneRowRelation
+
+
+-- !query
+DROP FUNCTION persistent_identifier_function
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_function, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_base_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_base_name, STRING, 'c1', false, false, false, false
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_nested_name()
+RETURNS STRING
+RETURN persistent_identifier_base_name()
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_nested_name, STRING, persistent_identifier_base_name(), false, false, false, false
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_nested_name()) FROM VALUES(1) AS T(c1)
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_nested_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 53,
+    "fragment" : "persistent_identifier_nested_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_nested_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_nested_name, false, false
+
+
+-- !query
+DROP FUNCTION persistent_identifier_base_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_base_name, false, false
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
+-- !query analysis
+CreateSQLFunctionCommand identifier_relation_name, STRING, 'identifier_function_table', false, true, false, false
+
+
+-- !query
+CREATE TABLE identifier_function_table(c1 INT) USING csv
+-- !query analysis
+CreateDataSourceTableCommand `spark_catalog`.`default`.`identifier_function_table`, false
+
+
+-- !query
+SELECT * FROM IDENTIFIER(identifier_relation_name())
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 51,
+    "fragment" : "identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_count()
+RETURNS BIGINT
+RETURN SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table'))
+-- !query analysis
+CreateSQLFunctionCommand identifier_relation_count, BIGINT, SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table')), false, true, false, false
+
+
+-- !query
+SELECT identifier_relation_count()
+-- !query analysis
+Project [identifier_relation_count() AS identifier_relation_count()#xL]
+:  +- Aggregate [count(1) AS count(1)#xL]
+:     +- SubqueryAlias spark_catalog.default.identifier_function_table
+:        +- Relation spark_catalog.default.identifier_function_table[c1#x] csv
++- Project
+   +- OneRowRelation
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_count
+-- !query analysis
+DropFunctionCommand identifier_relation_count, false, true
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
+-- !query analysis
+CreateSQLFunctionCommand spark_catalog.default.persistent_identifier_relation_name, STRING, 'identifier_function_table', false, false, false, false
+
+
+-- !query
+SELECT * FROM IDENTIFIER(persistent_identifier_relation_name())
+-- !query analysis
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 62,
+    "fragment" : "persistent_identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+DROP FUNCTION persistent_identifier_relation_name
+-- !query analysis
+DropFunctionCommand spark_catalog.default.persistent_identifier_relation_name, false, false
+
+
+-- !query
+DROP TABLE identifier_function_table
+-- !query analysis
+DropTable false, false
++- ResolvedIdentifier V2SessionCatalog(spark_catalog), default.identifier_function_table
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_name
+-- !query analysis
+DropFunctionCommand identifier_relation_name, false, true
+
+
 -- !query
 CREATE TABLE IDENTIFIER('tab')(c1 INT) USING CSV
 -- !query analysis
@@ -743,6 +1243,12 @@ CREATE TABLE t(col1 INT)
 CreateDataSourceTableCommand `spark_catalog`.`default`.`t`, false
 
 
+-- !query
+CREATE TABLE identifier_name_source(name STRING) USING csv
+-- !query analysis
+CreateDataSourceTableCommand `spark_catalog`.`default`.`identifier_name_source`, false
+
+
 -- !query
 SELECT * FROM IDENTIFIER((SELECT 't'))
 -- !query analysis
@@ -764,6 +1270,50 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 }
 
 
+-- !query
+SELECT * FROM IDENTIFIER((SELECT max(name) FROM identifier_name_source))
+-- !query analysis
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 71,
+    "fragment" : "(SELECT max(name) FROM identifier_name_source)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  (SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)
+)
+-- !query analysis
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 84,
+    "fragment" : "(SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)"
+  } ]
+}
+
+
 -- !query
 SELECT * FROM (SELECT IDENTIFIER((SELECT 'col1')) FROM IDENTIFIER((SELECT 't')))
 -- !query analysis
@@ -848,6 +1398,13 @@ org.apache.spark.sql.catalyst.parser.ParseException
 }
 
 
+-- !query
+DROP TABLE identifier_name_source
+-- !query analysis
+DropTable false, false
++- ResolvedIdentifier V2SessionCatalog(spark_catalog), default.identifier_name_source
+
+
 -- !query
 DROP TABLE t
 -- !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 1425004e9fcc..3c4c4f73e3bc 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
@@ -14,6 +14,7 @@ SELECT IDENTIFIER('`t`.c1') FROM VALUES(1) AS T(c1);
 SELECT IDENTIFIER('`c 1`') FROM VALUES(1) AS T(`c 1`);
 SELECT IDENTIFIER('``') FROM VALUES(1) AS T(``);
 SELECT IDENTIFIER('c' || '1') FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(concat('a', 'b')) FROM VALUES(1) AS T(ab);
 
 -- Table references
 CREATE SCHEMA IF NOT EXISTS s;
@@ -29,6 +30,7 @@ SELECT * FROM IDENTIFIER('tab');
 SELECT * FROM IDENTIFIER('s.tab');
 SELECT * FROM IDENTIFIER('`s`.`tab`');
 SELECT * FROM IDENTIFIER('t' || 'a' || 'b');
+SELECT * FROM IDENTIFIER(concat('t', 'ab'));
 
 USE SCHEMA default;
 DROP TABLE s.tab;
@@ -36,9 +38,73 @@ DROP SCHEMA s;
 
 -- Function reference
 SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1);
+SELECT IDENTIFIER(concat('COAL', 'ESCE'))(NULL, 1);
 SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1);
 SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1);
 
+VALUES(IDENTIFIER(abs(1)));
+SELECT * FROM IDENTIFIER(nullif('a', 'a'));
+
+-- Function resolution while computing an identifier name
+SELECT IDENTIFIER(max('c1')) FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(array_join(transform(array('c', '1'), element -> element), ''))
+FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(rand()) FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(row_number() OVER ()) FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(row_number() OVER (ORDER BY 'x')) FROM VALUES(1) AS T(c1);
+SELECT IDENTIFIER(explode(array('c1'))) FROM VALUES(1) AS T(c1);
+SELECT * FROM IDENTIFIER(max('identifier_function_table'));
+SELECT * FROM IDENTIFIER(row_number() OVER (ORDER BY 'x'));
+SELECT * FROM IDENTIFIER(
+  array_join(transform(array('identifier', '_function_table'), element -> element), '')
+);
+
+CREATE TEMPORARY FUNCTION identifier_name()
+RETURNS STRING
+RETURN 'c1';
+SELECT IDENTIFIER(identifier_name()) FROM VALUES(1) AS T(c1);
+DROP TEMPORARY FUNCTION identifier_name;
+
+CREATE FUNCTION persistent_identifier_name()
+RETURNS STRING
+RETURN 'c1';
+SELECT IDENTIFIER(persistent_identifier_name()) FROM VALUES(1) AS T(c1);
+DROP FUNCTION persistent_identifier_name;
+
+CREATE FUNCTION persistent_identifier_function(value INT)
+RETURNS INT
+RETURN value + 1;
+SELECT IDENTIFIER(concat('persistent_identifier_', 'function'))(1);
+DROP FUNCTION persistent_identifier_function;
+
+CREATE FUNCTION persistent_identifier_base_name()
+RETURNS STRING
+RETURN 'c1';
+CREATE FUNCTION persistent_identifier_nested_name()
+RETURNS STRING
+RETURN persistent_identifier_base_name();
+SELECT IDENTIFIER(persistent_identifier_nested_name()) FROM VALUES(1) AS T(c1);
+DROP FUNCTION persistent_identifier_nested_name;
+DROP FUNCTION persistent_identifier_base_name;
+
+CREATE TEMPORARY FUNCTION identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table';
+CREATE TABLE identifier_function_table(c1 INT) USING csv;
+SELECT * FROM IDENTIFIER(identifier_relation_name());
+CREATE TEMPORARY FUNCTION identifier_relation_count()
+RETURNS BIGINT
+RETURN SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table'));
+SELECT identifier_relation_count();
+DROP TEMPORARY FUNCTION identifier_relation_count;
+CREATE FUNCTION persistent_identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table';
+SELECT * FROM IDENTIFIER(persistent_identifier_relation_name());
+DROP FUNCTION persistent_identifier_relation_name;
+DROP TABLE identifier_function_table;
+DROP TEMPORARY FUNCTION identifier_relation_name;
+
 -- Table DDL
 CREATE TABLE IDENTIFIER('tab')(c1 INT) USING CSV;
 DROP TABLE IF EXISTS IDENTIFIER('ta' || 'b');
@@ -120,11 +186,17 @@ VALUES(IDENTIFIER(SUBSTR('HELLO', 1, RAND() + 1)));
 SELECT `IDENTIFIER`('abs')(c1) FROM VALUES(-1) AS T(c1);
 
 CREATE TABLE t(col1 INT);
+CREATE TABLE identifier_name_source(name STRING) USING csv;
 SELECT * FROM IDENTIFIER((SELECT 't'));
+SELECT * FROM IDENTIFIER((SELECT max(name) FROM identifier_name_source));
+SELECT * FROM IDENTIFIER(
+  (SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)
+);
 SELECT * FROM (SELECT IDENTIFIER((SELECT 'col1')) FROM IDENTIFIER((SELECT 't')));
 SELECT IDENTIFIER((SELECT 'col1')) FROM VALUES(1);
 SELECT col1, IDENTIFIER((SELECT col1)) FROM VALUES(1);
 SELECT IDENTIFIER((SELECT 'col1', 'col2')) FROM VALUES(1,2);
+DROP TABLE identifier_name_source;
 DROP TABLE t;
 
 CREATE TABLE IDENTIFIER(1)(c1 INT) USING csv;
diff --git a/sql/core/src/test/resources/sql-tests/results/identifier-clause-legacy.sql.out b/sql/core/src/test/resources/sql-tests/results/identifier-clause-legacy.sql.out
index 3b3bc11999c7..f881ebd53c72 100644
--- a/sql/core/src/test/resources/sql-tests/results/identifier-clause-legacy.sql.out
+++ b/sql/core/src/test/resources/sql-tests/results/identifier-clause-legacy.sql.out
@@ -63,16 +63,445 @@ struct<c1:int>
 1
 
 
+-- !query
+SELECT IDENTIFIER(concat('a', 'b')) FROM VALUES(1) AS T(ab)
+-- !query schema
+struct<ab:int>
+-- !query output
+1
+
+
 -- !query
 CREATE SCHEMA IF NOT EXISTS s
 -- !query schema
 struct<>
 -- !query output
-
+
+
+
+-- !query
+CREATE TABLE s.tab(c1 INT) USING CSV
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+USE SCHEMA s
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+INSERT INTO IDENTIFIER('ta' || 'b') VALUES(1)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DELETE FROM IDENTIFIER('ta' || 'b') WHERE 1=0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "DELETE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+UPDATE IDENTIFIER('ta' || 'b') SET c1 = 2
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkUnsupportedOperationException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "UPDATE TABLE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+MERGE INTO IDENTIFIER('ta' || 'b') AS t USING IDENTIFIER('ta' || 'b') AS s ON s.c1 = t.c1
+  WHEN MATCHED THEN UPDATE SET c1 = 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkUnsupportedOperationException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "MERGE INTO TABLE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER('tab')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('s.tab')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('`s`.`tab`')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('t' || 'a' || 'b')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER(concat('t', 'ab'))
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+USE SCHEMA default
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP TABLE s.tab
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP SCHEMA s
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1)
+-- !query schema
+struct<coalesce(NULL, 1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT IDENTIFIER(concat('COAL', 'ESCE'))(NULL, 1)
+-- !query schema
+struct<coalesce(NULL, 1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
+-- !query schema
+struct<abs(c1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1)
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+
+
+-- !query
+VALUES(IDENTIFIER(abs(1)))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.WRONG_TYPE",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "dataType" : "int",
+    "expr" : "abs(1)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "abs(1)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(nullif('a', 'a'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "nullif('a', 'a')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 41,
+    "fragment" : "nullif('a', 'a')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(max('c1')) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('c1')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 27,
+    "fragment" : "max('c1')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(array_join(transform(array('c', '1'), element -> element), ''))
+FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('c', '1'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 80,
+    "fragment" : "array_join(transform(array('c', '1'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(rand()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "rand()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "rand()"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER ()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "wf_expr" : "row_number()",
+    "wf_name" : "row_number"
+  }
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER (ORDER BY 'x')) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 50,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(explode(array('c1'))) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "explode(array('c1'))",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 38,
+    "fragment" : "explode(array('c1'))"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(max('identifier_function_table'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('identifier_function_table')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "max('identifier_function_table')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(row_number() OVER (ORDER BY 'x'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  array_join(transform(array('identifier', '_function_table'), element -> element), '')
+)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('identifier', '_function_table'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 113,
+    "fragment" : "array_join(transform(array('identifier', '_function_table'), element -> element), '')"
+  } ]
+}
 
 
 -- !query
-CREATE TABLE s.tab(c1 INT) USING CSV
+CREATE TEMPORARY FUNCTION identifier_name()
+RETURNS STRING
+RETURN 'c1'
 -- !query schema
 struct<>
 -- !query output
@@ -80,7 +509,30 @@ struct<>
 
 
 -- !query
-USE SCHEMA s
+SELECT IDENTIFIER(identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 35,
+    "fragment" : "identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_name
 -- !query schema
 struct<>
 -- !query output
@@ -88,7 +540,9 @@ struct<>
 
 
 -- !query
-INSERT INTO IDENTIFIER('ta' || 'b') VALUES(1)
+CREATE FUNCTION persistent_identifier_name()
+RETURNS STRING
+RETURN 'c1'
 -- !query schema
 struct<>
 -- !query output
@@ -96,88 +550,166 @@ struct<>
 
 
 -- !query
-DELETE FROM IDENTIFIER('ta' || 'b') WHERE 1=0
+SELECT IDENTIFIER(persistent_identifier_name()) FROM VALUES(1) AS T(c1)
 -- !query schema
 struct<>
 -- !query output
 org.apache.spark.sql.AnalysisException
 {
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
   "messageParameters" : {
-    "operation" : "DELETE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
+    "expr" : "spark_catalog.default.persistent_identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 46,
+    "fragment" : "persistent_identifier_name()"
+  } ]
 }
 
 
 -- !query
-UPDATE IDENTIFIER('ta' || 'b') SET c1 = 2
+DROP FUNCTION persistent_identifier_name
 -- !query schema
 struct<>
 -- !query output
-org.apache.spark.SparkUnsupportedOperationException
-{
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
-  "messageParameters" : {
-    "operation" : "UPDATE TABLE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
-}
+
 
 
 -- !query
-MERGE INTO IDENTIFIER('ta' || 'b') AS t USING IDENTIFIER('ta' || 'b') AS s ON s.c1 = t.c1
-  WHEN MATCHED THEN UPDATE SET c1 = 3
+CREATE FUNCTION persistent_identifier_function(value INT)
+RETURNS INT
+RETURN value + 1
 -- !query schema
 struct<>
 -- !query output
-org.apache.spark.SparkUnsupportedOperationException
+
+
+
+-- !query
+SELECT IDENTIFIER(concat('persistent_identifier_', 'function'))(1)
+-- !query schema
+struct<spark_catalog.default.persistent_identifier_function(1):int>
+-- !query output
+2
+
+
+-- !query
+DROP FUNCTION persistent_identifier_function
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_base_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_nested_name()
+RETURNS STRING
+RETURN persistent_identifier_base_name()
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_nested_name()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
 {
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
   "messageParameters" : {
-    "operation" : "MERGE INTO TABLE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
+    "expr" : "spark_catalog.default.persistent_identifier_nested_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 53,
+    "fragment" : "persistent_identifier_nested_name()"
+  } ]
 }
 
 
 -- !query
-SELECT * FROM IDENTIFIER('tab')
+DROP FUNCTION persistent_identifier_nested_name
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('s.tab')
+DROP FUNCTION persistent_identifier_base_name
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('`s`.`tab`')
+CREATE TEMPORARY FUNCTION identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('t' || 'a' || 'b')
+CREATE TABLE identifier_function_table(c1 INT) USING csv
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-USE SCHEMA default
+SELECT * FROM IDENTIFIER(identifier_relation_name())
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 51,
+    "fragment" : "identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_count()
+RETURNS BIGINT
+RETURN SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table'))
 -- !query schema
 struct<>
 -- !query output
@@ -185,7 +717,15 @@ struct<>
 
 
 -- !query
-DROP TABLE s.tab
+SELECT identifier_relation_count()
+-- !query schema
+struct<identifier_relation_count():bigint>
+-- !query output
+0
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_count
 -- !query schema
 struct<>
 -- !query output
@@ -193,7 +733,9 @@ struct<>
 
 
 -- !query
-DROP SCHEMA s
+CREATE FUNCTION persistent_identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
 -- !query schema
 struct<>
 -- !query output
@@ -201,27 +743,50 @@ struct<>
 
 
 -- !query
-SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1)
+SELECT * FROM IDENTIFIER(persistent_identifier_relation_name())
 -- !query schema
-struct<coalesce(NULL, 1):int>
+struct<>
 -- !query output
-1
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 62,
+    "fragment" : "persistent_identifier_relation_name()"
+  } ]
+}
 
 
 -- !query
-SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
+DROP FUNCTION persistent_identifier_relation_name
 -- !query schema
-struct<abs(c1):int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1)
+DROP TABLE identifier_function_table
 -- !query schema
-struct<id:bigint>
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_name
+-- !query schema
+struct<>
 -- !query output
-0
+
 
 
 -- !query
@@ -854,6 +1419,14 @@ struct<>
 
 
 
+-- !query
+CREATE TABLE identifier_name_source(name STRING) USING csv
+-- !query schema
+struct<>
+-- !query output
+
+
+
 -- !query
 SELECT * FROM IDENTIFIER((SELECT 't'))
 -- !query schema
@@ -877,6 +1450,54 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 }
 
 
+-- !query
+SELECT * FROM IDENTIFIER((SELECT max(name) FROM identifier_name_source))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 71,
+    "fragment" : "(SELECT max(name) FROM identifier_name_source)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  (SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)
+)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 84,
+    "fragment" : "(SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)"
+  } ]
+}
+
+
 -- !query
 SELECT * FROM (SELECT IDENTIFIER((SELECT 'col1')) FROM IDENTIFIER((SELECT 't')))
 -- !query schema
@@ -969,6 +1590,14 @@ org.apache.spark.sql.catalyst.parser.ParseException
 }
 
 
+-- !query
+DROP TABLE identifier_name_source
+-- !query schema
+struct<>
+-- !query output
+
+
+
 -- !query
 DROP TABLE t
 -- !query schema
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 a45c2da46ada..045348cf7ea0 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
@@ -63,16 +63,445 @@ struct<c1:int>
 1
 
 
+-- !query
+SELECT IDENTIFIER(concat('a', 'b')) FROM VALUES(1) AS T(ab)
+-- !query schema
+struct<ab:int>
+-- !query output
+1
+
+
 -- !query
 CREATE SCHEMA IF NOT EXISTS s
 -- !query schema
 struct<>
 -- !query output
-
+
+
+
+-- !query
+CREATE TABLE s.tab(c1 INT) USING CSV
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+USE SCHEMA s
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+INSERT INTO IDENTIFIER('ta' || 'b') VALUES(1)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DELETE FROM IDENTIFIER('ta' || 'b') WHERE 1=0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "DELETE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+UPDATE IDENTIFIER('ta' || 'b') SET c1 = 2
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkUnsupportedOperationException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "UPDATE TABLE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+MERGE INTO IDENTIFIER('ta' || 'b') AS t USING IDENTIFIER('ta' || 'b') AS s ON s.c1 = t.c1
+  WHEN MATCHED THEN UPDATE SET c1 = 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.SparkUnsupportedOperationException
+{
+  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
+  "sqlState" : "0A000",
+  "messageParameters" : {
+    "operation" : "MERGE INTO TABLE",
+    "tableName" : "`spark_catalog`.`s`.`tab`"
+  }
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER('tab')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('s.tab')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('`s`.`tab`')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('t' || 'a' || 'b')
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER(concat('t', 'ab'))
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+
+
+-- !query
+USE SCHEMA default
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP TABLE s.tab
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP SCHEMA s
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1)
+-- !query schema
+struct<coalesce(NULL, 1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT IDENTIFIER(concat('COAL', 'ESCE'))(NULL, 1)
+-- !query schema
+struct<coalesce(NULL, 1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
+-- !query schema
+struct<abs(c1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1)
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+
+
+-- !query
+VALUES(IDENTIFIER(abs(1)))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.WRONG_TYPE",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "dataType" : "int",
+    "expr" : "abs(1)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "abs(1)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(nullif('a', 'a'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "nullif('a', 'a')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 41,
+    "fragment" : "nullif('a', 'a')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(max('c1')) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('c1')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 27,
+    "fragment" : "max('c1')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(array_join(transform(array('c', '1'), element -> element), ''))
+FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('c', '1'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 80,
+    "fragment" : "array_join(transform(array('c', '1'), element -> element), '')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(rand()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "rand()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 24,
+    "fragment" : "rand()"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER ()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "wf_expr" : "row_number()",
+    "wf_name" : "row_number"
+  }
+}
+
+
+-- !query
+SELECT IDENTIFIER(row_number() OVER (ORDER BY 'x')) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 50,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT IDENTIFIER(explode(array('c1'))) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "explode(array('c1'))",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 38,
+    "fragment" : "explode(array('c1'))"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(max('identifier_function_table'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "max('identifier_function_table')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "max('identifier_function_table')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(row_number() OVER (ORDER BY 'x'))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "row_number() OVER (ORDER BY 'x' ASC NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 57,
+    "fragment" : "row_number() OVER (ORDER BY 'x')"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  array_join(transform(array('identifier', '_function_table'), element -> element), '')
+)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "array_join(transform(array('identifier', '_function_table'), lambdafunction(namedlambdavariable(), namedlambdavariable())), '')",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 113,
+    "fragment" : "array_join(transform(array('identifier', '_function_table'), element -> element), '')"
+  } ]
+}
 
 
 -- !query
-CREATE TABLE s.tab(c1 INT) USING CSV
+CREATE TEMPORARY FUNCTION identifier_name()
+RETURNS STRING
+RETURN 'c1'
 -- !query schema
 struct<>
 -- !query output
@@ -80,7 +509,30 @@ struct<>
 
 
 -- !query
-USE SCHEMA s
+SELECT IDENTIFIER(identifier_name()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 35,
+    "fragment" : "identifier_name()"
+  } ]
+}
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_name
 -- !query schema
 struct<>
 -- !query output
@@ -88,7 +540,9 @@ struct<>
 
 
 -- !query
-INSERT INTO IDENTIFIER('ta' || 'b') VALUES(1)
+CREATE FUNCTION persistent_identifier_name()
+RETURNS STRING
+RETURN 'c1'
 -- !query schema
 struct<>
 -- !query output
@@ -96,88 +550,166 @@ struct<>
 
 
 -- !query
-DELETE FROM IDENTIFIER('ta' || 'b') WHERE 1=0
+SELECT IDENTIFIER(persistent_identifier_name()) FROM VALUES(1) AS T(c1)
 -- !query schema
 struct<>
 -- !query output
 org.apache.spark.sql.AnalysisException
 {
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
   "messageParameters" : {
-    "operation" : "DELETE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
+    "expr" : "spark_catalog.default.persistent_identifier_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 46,
+    "fragment" : "persistent_identifier_name()"
+  } ]
 }
 
 
 -- !query
-UPDATE IDENTIFIER('ta' || 'b') SET c1 = 2
+DROP FUNCTION persistent_identifier_name
 -- !query schema
 struct<>
 -- !query output
-org.apache.spark.SparkUnsupportedOperationException
-{
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
-  "messageParameters" : {
-    "operation" : "UPDATE TABLE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
-}
+
 
 
 -- !query
-MERGE INTO IDENTIFIER('ta' || 'b') AS t USING IDENTIFIER('ta' || 'b') AS s ON s.c1 = t.c1
-  WHEN MATCHED THEN UPDATE SET c1 = 3
+CREATE FUNCTION persistent_identifier_function(value INT)
+RETURNS INT
+RETURN value + 1
 -- !query schema
 struct<>
 -- !query output
-org.apache.spark.SparkUnsupportedOperationException
+
+
+
+-- !query
+SELECT IDENTIFIER(concat('persistent_identifier_', 'function'))(1)
+-- !query schema
+struct<spark_catalog.default.persistent_identifier_function(1):int>
+-- !query output
+2
+
+
+-- !query
+DROP FUNCTION persistent_identifier_function
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_base_name()
+RETURNS STRING
+RETURN 'c1'
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE FUNCTION persistent_identifier_nested_name()
+RETURNS STRING
+RETURN persistent_identifier_base_name()
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT IDENTIFIER(persistent_identifier_nested_name()) FROM VALUES(1) AS T(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
 {
-  "errorClass" : "UNSUPPORTED_FEATURE.TABLE_OPERATION",
-  "sqlState" : "0A000",
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
   "messageParameters" : {
-    "operation" : "MERGE INTO TABLE",
-    "tableName" : "`spark_catalog`.`s`.`tab`"
-  }
+    "expr" : "spark_catalog.default.persistent_identifier_nested_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 19,
+    "stopIndex" : 53,
+    "fragment" : "persistent_identifier_nested_name()"
+  } ]
 }
 
 
 -- !query
-SELECT * FROM IDENTIFIER('tab')
+DROP FUNCTION persistent_identifier_nested_name
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('s.tab')
+DROP FUNCTION persistent_identifier_base_name
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('`s`.`tab`')
+CREATE TEMPORARY FUNCTION identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('t' || 'a' || 'b')
+CREATE TABLE identifier_function_table(c1 INT) USING csv
 -- !query schema
-struct<c1:int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-USE SCHEMA default
+SELECT * FROM IDENTIFIER(identifier_relation_name())
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 51,
+    "fragment" : "identifier_relation_name()"
+  } ]
+}
+
+
+-- !query
+CREATE TEMPORARY FUNCTION identifier_relation_count()
+RETURNS BIGINT
+RETURN SELECT count(*) FROM IDENTIFIER(concat('identifier_function_', 'table'))
 -- !query schema
 struct<>
 -- !query output
@@ -185,7 +717,15 @@ struct<>
 
 
 -- !query
-DROP TABLE s.tab
+SELECT identifier_relation_count()
+-- !query schema
+struct<identifier_relation_count():bigint>
+-- !query output
+0
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_count
 -- !query schema
 struct<>
 -- !query output
@@ -193,7 +733,9 @@ struct<>
 
 
 -- !query
-DROP SCHEMA s
+CREATE FUNCTION persistent_identifier_relation_name()
+RETURNS STRING
+RETURN 'identifier_function_table'
 -- !query schema
 struct<>
 -- !query output
@@ -201,27 +743,50 @@ struct<>
 
 
 -- !query
-SELECT IDENTIFIER('COAL' || 'ESCE')(NULL, 1)
+SELECT * FROM IDENTIFIER(persistent_identifier_relation_name())
 -- !query schema
-struct<coalesce(NULL, 1):int>
+struct<>
 -- !query output
-1
+org.apache.spark.sql.AnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "spark_catalog.default.persistent_identifier_relation_name()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 62,
+    "fragment" : "persistent_identifier_relation_name()"
+  } ]
+}
 
 
 -- !query
-SELECT IDENTIFIER('abs')(c1) FROM VALUES(-1) AS T(c1)
+DROP FUNCTION persistent_identifier_relation_name
 -- !query schema
-struct<abs(c1):int>
+struct<>
 -- !query output
-1
+
 
 
 -- !query
-SELECT * FROM IDENTIFIER('ra' || 'nge')(0, 1)
+DROP TABLE identifier_function_table
 -- !query schema
-struct<id:bigint>
+struct<>
+-- !query output
+
+
+
+-- !query
+DROP TEMPORARY FUNCTION identifier_relation_name
+-- !query schema
+struct<>
 -- !query output
-0
+
 
 
 -- !query
@@ -854,6 +1419,14 @@ struct<>
 
 
 
+-- !query
+CREATE TABLE identifier_name_source(name STRING) USING csv
+-- !query schema
+struct<>
+-- !query output
+
+
+
 -- !query
 SELECT * FROM IDENTIFIER((SELECT 't'))
 -- !query schema
@@ -877,6 +1450,54 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException
 }
 
 
+-- !query
+SELECT * FROM IDENTIFIER((SELECT max(name) FROM identifier_name_source))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 26,
+    "stopIndex" : 71,
+    "fragment" : "(SELECT max(name) FROM identifier_name_source)"
+  } ]
+}
+
+
+-- !query
+SELECT * FROM IDENTIFIER(
+  (SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)
+)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+  "errorClass" : "NOT_A_CONSTANT_STRING.NOT_CONSTANT",
+  "sqlState" : "42601",
+  "messageParameters" : {
+    "expr" : "scalarsubquery()",
+    "name" : "IDENTIFIER"
+  },
+  "queryContext" : [ {
+    "objectType" : "",
+    "objectName" : "",
+    "startIndex" : 29,
+    "stopIndex" : 84,
+    "fragment" : "(SELECT 'x' FROM (SELECT 1) WHERE explode(array(1)) = 1)"
+  } ]
+}
+
+
 -- !query
 SELECT * FROM (SELECT IDENTIFIER((SELECT 'col1')) FROM IDENTIFIER((SELECT 't')))
 -- !query schema
@@ -969,6 +1590,14 @@ org.apache.spark.sql.catalyst.parser.ParseException
 }
 
 
+-- !query
+DROP TABLE identifier_name_source
+-- !query schema
+struct<>
+-- !query output
+
+
+
 -- !query
 DROP TABLE t
 -- !query schema


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org