cloud-fan commented on code in PR #53437:
URL: https://github.com/apache/spark/pull/53437#discussion_r2609668479


##########
sql/core/src/main/scala/org/apache/spark/sql/execution/command/DescribeProcedureCommand.scala:
##########
@@ -45,34 +42,63 @@ case class DescribeProcedureCommand(
 
   override def run(sparkSession: SparkSession): Seq[Row] = {
     child match {
-      case ResolvedIdentifier(catalog, ident) =>
-        val procedure = load(catalog.asProcedureCatalog, ident)
-        describeV2Procedure(procedure)
+      case ResolvedProcedure(catalog, ident, procedure) =>
+        describeV2Procedure(procedure.asInstanceOf[UnboundProcedure])
       case _ =>
         throw SparkException.internalError(s"Invalid procedure identifier: 
${child.getClass}")
     }
   }
 
-  private def load(catalog: ProcedureCatalog, ident: Identifier): 
UnboundProcedure = {
-    try {
-      catalog.loadProcedure(ident)
-    } catch {
-      case e: Exception if !e.isInstanceOf[SparkThrowable] =>
-        val nameParts = catalog.name +: ident.asMultipartIdentifier
-        throw QueryCompilationErrors.failedToLoadRoutineError(nameParts, e)
-    }
-  }
 
   private def describeV2Procedure(procedure: UnboundProcedure): Seq[Row] = {
     val buffer = new ArrayBuffer[(String, String)]
     append(buffer, "Procedure:", procedure.name())
     append(buffer, "Description:", procedure.description())
 
+    // UnboundProcedure requires binding to retrieve parameters. We try to 
bind with an empty
+    // argument list to get the parameters. If the procedure requires 
arguments, binding might
+    // fail. In that case, we suppress the exception and just show the 
procedure metadata
+    // without parameters.
+    try {
+      val bound = procedure.bind(new StructType())
+      val params = bound.parameters()
+      if (params != null && params.nonEmpty) {
+        val formattedParams = formatProcedureParameters(params)
+        append(buffer, "Parameters:", formattedParams.head)
+        formattedParams.tail.foreach(s => append(buffer, "", s))
+      } else {
+        append(buffer, "Parameters:", "()")
+      }
+    } catch {
+      case _: Exception =>
+        // Ignore if binding fails
+    }
+
     val keys = tabulate(buffer.map(_._1).toSeq)
     val values = buffer.map(_._2)
     keys.zip(values).map { case (key, value) => Row(s"$key $value") }
   }
 
+  // This helper is needed because the V2 Procedure API returns an array of 
ProcedureParameter,
+  // which differs from the StructType used by internal stored procedures 
(handled by
+  // formatParameters).
+  private def formatProcedureParameters(params: Array[ProcedureParameter]): 
Seq[String] = {
+    val modes = tabulate(params.map(_.mode().toString).toSeq)

Review Comment:
   The impl here is really awkward, can we iterate `param` just once?
   ```
   params.map { param =>
     s"${param.mode} ${param.name} ..."
   }
   ```



-- 
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