dtenedor commented on code in PR #53941:
URL: https://github.com/apache/spark/pull/53941#discussion_r2728880279
##########
sql/core/src/main/scala/org/apache/spark/sql/execution/SparkSqlParser.scala:
##########
@@ -410,15 +411,48 @@ class SparkSqlAstBuilder extends AstBuilder {
/**
* Create a [[SetCatalogCommand]] logical command.
+ *
+ * SET CATALOG is case-sensitive and supports multiple forms:
+ *
+ * - Session temp variable: SET CATALOG var_name (where var_name is a
declared variable)
+ * - Simple identifier: SET CATALOG my_catalog
+ * (tries to resolve as session temp variable first, then uses as
literal catalog name)
+ * - String literal: SET CATALOG 'my_catalog'
+ * - identifier() function: SET CATALOG IDENTIFIER('my_catalog') or
IDENTIFIER(var_name)
+ * - Other foldable expressions: SET CATALOG CAST('my_catalog' AS STRING),
+ * CONCAT('my', '_catalog')
*/
override def visitSetCatalog(ctx: SetCatalogContext): LogicalPlan =
withOrigin(ctx) {
- withCatalogIdentClause(ctx.catalogIdentifierReference, identifiers => {
- if (identifiers.size > 1) {
- // can occur when user put multipart string in IDENTIFIER(...) clause
- throw QueryParsingErrors.invalidNameForSetCatalog(identifiers, ctx)
+ val expr = expression(ctx.expression())
+
+ def buildSetCatalogCommand(nameParts: Seq[String]): SetCatalogCommand = {
+ if (nameParts.size > 1) {
+ throw QueryParsingErrors.invalidNameForSetCatalog(nameParts, ctx)
}
- SetCatalogCommand(identifiers.head)
- })
+ SetCatalogCommand(nameParts.head)
+ }
+
+ expr match {
+ // UnresolvedAttribute - try to resolve as variable, fallback to literal
+ // Resolution order: (1) session temp variable, (2) literal catalog name
+ case UnresolvedAttribute(nameParts) =>
+ PlanWithUnresolvedIdentifierAndFallback(
Review Comment:
The rule could look something like:
```
import org.apache.spark.sql.catalyst.analysis._
import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.plans.logical._
import org.apache.spark.sql.types.StringType
/**
* Replaces unresolved catalog name attributes in SetCatalogCommand
* with a string literal.
*/
object ResolveSetCatalogCommand extends Rule[LogicalPlan] {
override def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperators
{
case cmd @ SetCatalogCommand(expr) =>
val resolvedExpr = expr match {
case UnresolvedAttribute(nameParts) =>
// Convert `SET CATALOG foo` into Literal("foo")
Literal(nameParts.mkString("."), StringType)
case other =>
other
}
cmd.copy(catalogNameExpr = resolvedExpr)
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]