srielau commented on code in PR #55569:
URL: https://github.com/apache/spark/pull/55569#discussion_r3170156491
##########
sql/core/src/test/scala/org/apache/spark/sql/SetPathSuite.scala:
##########
@@ -361,6 +361,50 @@ class SetPathSuite extends SharedSparkSession {
}
}
+ test("PATH enabled: case-sensitive mode does not treat differently cased
entries as duplicates") {
+ withSQLConf(
+ SQLConf.PATH_ENABLED.key -> "true",
+ SQLConf.CASE_SENSITIVE.key -> "true") {
+ sql("SET PATH = spark_catalog.DEFAULT, spark_catalog.default")
+ val stored = spark.sessionState.catalogManager.sessionPathEntries.get
+ val rendered = stored.map(_.resolve("ignored", Nil).mkString("."))
+ assert(rendered === Seq("spark_catalog.DEFAULT",
"spark_catalog.default"))
+ }
+ }
+
+ test("PATH enabled: unqualified session variable lookup follows PATH") {
+ withPathEnabled {
+ sql("DECLARE VARIABLE system.session.path_var_gate = 7")
+ try {
+ sql("SET PATH = spark_catalog.default")
+ checkError(
+ exception = intercept[AnalysisException] {
+ sql("DROP TEMPORARY VARIABLE path_var_gate")
+ },
+ condition = "UNRESOLVED_VARIABLE",
+ sqlState = "42883",
+ parameters = Map(
+ "variableName" -> "`path_var_gate`",
+ "searchPath" -> "`SYSTEM`.`SESSION`"))
+
+ sql("SET PATH = spark_catalog.default, system.session")
+ sql("DROP TEMPORARY VARIABLE path_var_gate")
+ } finally {
+ sql("DROP TEMPORARY VARIABLE IF EXISTS system.session.path_var_gate")
+ }
+ }
+ }
+
+ test("PATH enabled: current_path does not accept arguments") {
+ withPathEnabled {
+ val e = intercept[AnalysisException] {
+ sql("SET PATH = DEFAULT_PATH")
Review Comment:
Good point, thanks. Fixed in e428a503e7e by removing `SET PATH =
DEFAULT_PATH` from inside the `intercept` block so the assertion is scoped only
to the arg-count error from `current_path(1)`.
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/connector/catalog/CatalogManager.scala:
##########
@@ -349,4 +350,45 @@ private[sql] object CatalogManager {
compact(JArray(entries.map(parts =>
JArray(parts.map(JString(_)).toList)).toList))
}
+
+ /**
+ * Parse a stored frozen path string from view/function metadata.
+ * Returns None if the payload is malformed.
+ */
+ def deserializePathEntries(storedPathStr: String): Option[Seq[Seq[String]]]
= {
+ import org.json4s.JsonAST.{JArray, JString}
+ import org.json4s.jackson.JsonMethods.parse
+
+ Try(parse(storedPathStr)).toOption match {
+ case Some(JArray(entries)) =>
+ entries.foldLeft(Option(Seq.empty[Seq[String]])) { (acc, entry) =>
+ acc.flatMap { collected =>
+ entry match {
+ case JArray(parts) =>
+ val strings = parts.collect { case JString(s) => s }
+ if (strings.size == parts.size) Some(collected :+ strings)
+ else {
+ logWarning(
+ s"Invalid stored SQL path metadata: expected string parts
in array entry: " +
+ s"$storedPathStr")
+ None
+ }
+ case _ =>
+ logWarning(
+ s"Invalid stored SQL path metadata: expected array entry but
found non-array: " +
+ s"$storedPathStr")
+ None
+ }
+ }
+ }
+ case Some(_) =>
+ logWarning(
+ s"Invalid stored SQL path metadata: expected top-level JSON array:
$storedPathStr")
+ None
+ case None =>
+ logWarning(
+ s"Invalid stored SQL path metadata: failed to parse JSON payload:
$storedPathStr")
+ None
Review Comment:
Good question. I kept this as warning+fallback intentionally for
compatibility with existing persisted metadata: failing analysis hard on
malformed/stale payloads could make previously usable views/functions suddenly
fail at query time after upgrade or manual metadata drift. The warning makes
corruption observable while preserving operability. If we want to hard-fail in
the future, we can gate it behind a strict config and migrate safely.
--
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]