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]

Reply via email to