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

mchades pushed a commit to branch udf-poc
in repository https://gitbox.apache.org/repos/asf/gravitino.git

commit ae25f2e2fd124c85cf9814680f8e4a39e430b58a
Author: mchades <[email protected]>
AuthorDate: Wed Dec 17 20:22:48 2025 +0800

    implement RESTful API for function operations
---
 .../apache/gravitino/dto/function/FunctionDTO.java | 11 ++++-
 .../gravitino/dto/function/FunctionImplDTO.java    | 55 +++++++++++++++++-----
 .../gravitino/dto/function/FunctionParamDTO.java   |  8 ++--
 .../dto/requests/FunctionUpdateRequest.java        |  3 ++
 .../apache/gravitino/dto/util/DTOConverters.java   | 13 ++++-
 rfc/Design of Functions Management in Gravitino.md | 19 ++++++++
 .../server/web/rest/FunctionOperations.java        | 16 +++----
 7 files changed, 100 insertions(+), 25 deletions(-)

diff --git 
a/common/src/main/java/org/apache/gravitino/dto/function/FunctionDTO.java 
b/common/src/main/java/org/apache/gravitino/dto/function/FunctionDTO.java
index b43043e4a8..cca538d29d 100644
--- a/common/src/main/java/org/apache/gravitino/dto/function/FunctionDTO.java
+++ b/common/src/main/java/org/apache/gravitino/dto/function/FunctionDTO.java
@@ -18,6 +18,8 @@
  */
 package org.apache.gravitino.dto.function;
 
+import static org.apache.gravitino.dto.util.DTOConverters.toFunctionArg;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -33,6 +35,7 @@ import org.apache.gravitino.function.FunctionImpl;
 import org.apache.gravitino.function.FunctionSignature;
 import org.apache.gravitino.function.FunctionType;
 import org.apache.gravitino.json.JsonUtils;
+import org.apache.gravitino.rel.Column;
 import org.apache.gravitino.rel.types.Type;
 
 /** DTO for {@link Function}. */
@@ -133,7 +136,12 @@ public class FunctionDTO implements Function {
                                 param.name(),
                                 param.dataType(),
                                 param.comment(),
-                                param.defaultValue()))
+                                (param.defaultValue() == null
+                                        || param
+                                            .defaultValue()
+                                            
.equals(Column.DEFAULT_VALUE_NOT_SET))
+                                    ? Column.DEFAULT_VALUE_NOT_SET
+                                    : toFunctionArg(param.defaultValue())))
                     .toArray(FunctionParamDTO[]::new)))
         .withFunctionType(function.functionType())
         .withDeterministic(function.deterministic())
@@ -216,6 +224,7 @@ public class FunctionDTO implements Function {
     return version;
   }
 
+  /** Builder for {@link FunctionDTO}. */
   public static class Builder {
     private FunctionSignatureDTO signature;
     private FunctionType functionType;
diff --git 
a/common/src/main/java/org/apache/gravitino/dto/function/FunctionImplDTO.java 
b/common/src/main/java/org/apache/gravitino/dto/function/FunctionImplDTO.java
index 0542582d25..5f87e3b858 100644
--- 
a/common/src/main/java/org/apache/gravitino/dto/function/FunctionImplDTO.java
+++ 
b/common/src/main/java/org/apache/gravitino/dto/function/FunctionImplDTO.java
@@ -43,6 +43,11 @@ import org.apache.gravitino.rest.RESTRequest;
 })
 public interface FunctionImplDTO extends RESTRequest {
 
+  /**
+   * Converts this DTO to a {@link FunctionImpl}.
+   *
+   * @return The converted function implementation.
+   */
   FunctionImpl toFunctionImpl();
 
   /** DTO for SQL implementation. */
@@ -51,8 +56,8 @@ public interface FunctionImplDTO extends RESTRequest {
   @ToString
   class SqlImplDTO implements FunctionImplDTO {
 
-    @JsonProperty("dialect")
-    private String dialect;
+    @JsonProperty("runtime")
+    private String runtime;
 
     @JsonProperty("sql")
     private String sql;
@@ -70,17 +75,17 @@ public interface FunctionImplDTO extends RESTRequest {
     /**
      * Creates a SQL implementation DTO.
      *
-     * @param dialect SQL dialect.
+     * @param runtime Target runtime.
      * @param sql SQL text.
      * @param resources Optional resources.
      * @param properties Implementation properties.
      */
     public SqlImplDTO(
-        String dialect,
+        String runtime,
         String sql,
         FunctionResourcesDTO resources,
         Map<String, String> properties) {
-      this.dialect = dialect;
+      this.runtime = runtime;
       this.sql = sql;
       this.resources = resources;
       this.properties = properties;
@@ -90,13 +95,16 @@ public interface FunctionImplDTO extends RESTRequest {
     @Override
     public FunctionImpl toFunctionImpl() {
       return FunctionImpl.ofSql(
-          dialect, sql, resources == null ? null : resources.toResources(), 
properties);
+          FunctionImpl.RuntimeType.fromString(runtime),
+          sql,
+          resources == null ? null : resources.toResources(),
+          properties);
     }
 
     /** {@inheritDoc} */
     @Override
     public void validate() throws IllegalArgumentException {
-      Preconditions.checkArgument(StringUtils.isNotBlank(dialect), 
"\"dialect\" is required");
+      Preconditions.checkArgument(StringUtils.isNotBlank(runtime), 
"\"runtime\" is required");
       Preconditions.checkArgument(StringUtils.isNotBlank(sql), "\"sql\" is 
required");
       if (resources != null) {
         resources.toResources();
@@ -111,6 +119,9 @@ public interface FunctionImplDTO extends RESTRequest {
   @NoArgsConstructor(access = AccessLevel.PRIVATE)
   class JavaImplDTO implements FunctionImplDTO {
 
+    @JsonProperty("runtime")
+    private String runtime;
+
     @JsonProperty("className")
     private String className;
 
@@ -123,12 +134,17 @@ public interface FunctionImplDTO extends RESTRequest {
     /**
      * Creates a Java implementation DTO.
      *
+     * @param runtime Target runtime.
      * @param className Fully qualified class name.
      * @param resources Optional resources.
      * @param properties Implementation properties.
      */
     public JavaImplDTO(
-        String className, FunctionResourcesDTO resources, Map<String, String> 
properties) {
+        String runtime,
+        String className,
+        FunctionResourcesDTO resources,
+        Map<String, String> properties) {
+      this.runtime = runtime;
       this.className = className;
       this.resources = resources;
       this.properties = properties;
@@ -138,12 +154,16 @@ public interface FunctionImplDTO extends RESTRequest {
     @Override
     public FunctionImpl toFunctionImpl() {
       return FunctionImpl.ofJava(
-          className, resources == null ? null : resources.toResources(), 
properties);
+          FunctionImpl.RuntimeType.fromString(runtime),
+          className,
+          resources == null ? null : resources.toResources(),
+          properties);
     }
 
     /** {@inheritDoc} */
     @Override
     public void validate() throws IllegalArgumentException {
+      Preconditions.checkArgument(StringUtils.isNotBlank(runtime), 
"\"runtime\" is required");
       Preconditions.checkArgument(StringUtils.isNotBlank(className), 
"\"className\" is required");
       if (resources != null) {
         resources.toResources();
@@ -158,6 +178,9 @@ public interface FunctionImplDTO extends RESTRequest {
   @NoArgsConstructor(access = AccessLevel.PRIVATE)
   class PythonImplDTO implements FunctionImplDTO {
 
+    @JsonProperty("runtime")
+    private String runtime;
+
     @JsonProperty("handler")
     private String handler;
 
@@ -173,16 +196,19 @@ public interface FunctionImplDTO extends RESTRequest {
     /**
      * Creates a Python implementation DTO.
      *
+     * @param runtime Target runtime.
      * @param handler Python handler entry.
      * @param codeBlock Inline code block.
      * @param resources Optional resources.
      * @param properties Implementation properties.
      */
     public PythonImplDTO(
+        String runtime,
         String handler,
         String codeBlock,
         FunctionResourcesDTO resources,
         Map<String, String> properties) {
+      this.runtime = runtime;
       this.handler = handler;
       this.codeBlock = codeBlock;
       this.resources = resources;
@@ -193,12 +219,17 @@ public interface FunctionImplDTO extends RESTRequest {
     @Override
     public FunctionImpl toFunctionImpl() {
       return FunctionImpl.ofPython(
-          handler, codeBlock, resources == null ? null : 
resources.toResources(), properties);
+          FunctionImpl.RuntimeType.fromString(runtime),
+          handler,
+          codeBlock,
+          resources == null ? null : resources.toResources(),
+          properties);
     }
 
     /** {@inheritDoc} */
     @Override
     public void validate() throws IllegalArgumentException {
+      Preconditions.checkArgument(StringUtils.isNotBlank(runtime), 
"\"runtime\" is required");
       Preconditions.checkArgument(StringUtils.isNotBlank(handler), 
"\"handler\" is required");
       if (resources != null) {
         resources.toResources();
@@ -216,7 +247,7 @@ public interface FunctionImplDTO extends RESTRequest {
     if (impl instanceof org.apache.gravitino.function.SQLImpl) {
       org.apache.gravitino.function.SQLImpl sqlImpl = 
(org.apache.gravitino.function.SQLImpl) impl;
       return new SqlImplDTO(
-          sqlImpl.dialect(),
+          sqlImpl.runtime().name(),
           sqlImpl.sql(),
           new FunctionResourcesDTO(sqlImpl.resources()),
           sqlImpl.properties());
@@ -224,6 +255,7 @@ public interface FunctionImplDTO extends RESTRequest {
       org.apache.gravitino.function.JavaImpl javaImpl =
           (org.apache.gravitino.function.JavaImpl) impl;
       return new JavaImplDTO(
+          javaImpl.runtime().name(),
           javaImpl.className(),
           new FunctionResourcesDTO(javaImpl.resources()),
           javaImpl.properties());
@@ -231,6 +263,7 @@ public interface FunctionImplDTO extends RESTRequest {
       org.apache.gravitino.function.PythonImpl pythonImpl =
           (org.apache.gravitino.function.PythonImpl) impl;
       return new PythonImplDTO(
+          pythonImpl.runtime().name(),
           pythonImpl.handler(),
           pythonImpl.codeBlock(),
           new FunctionResourcesDTO(pythonImpl.resources()),
diff --git 
a/common/src/main/java/org/apache/gravitino/dto/function/FunctionParamDTO.java 
b/common/src/main/java/org/apache/gravitino/dto/function/FunctionParamDTO.java
index 44a5ee6769..86f9b6cd05 100644
--- 
a/common/src/main/java/org/apache/gravitino/dto/function/FunctionParamDTO.java
+++ 
b/common/src/main/java/org/apache/gravitino/dto/function/FunctionParamDTO.java
@@ -28,6 +28,7 @@ import lombok.ToString;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.gravitino.function.FunctionParam;
 import org.apache.gravitino.json.JsonUtils;
+import org.apache.gravitino.rel.Column;
 import org.apache.gravitino.rel.expressions.Expression;
 import org.apache.gravitino.rel.types.Type;
 import org.apache.gravitino.rest.RESTRequest;
@@ -52,7 +53,7 @@ public class FunctionParamDTO implements FunctionParam, 
RESTRequest {
   @JsonInclude(JsonInclude.Include.NON_EMPTY)
   @JsonSerialize(using = JsonUtils.ColumnDefaultValueSerializer.class)
   @JsonDeserialize(using = JsonUtils.ColumnDefaultValueDeserializer.class)
-  private Expression defaultValue = FunctionParam.DEFAULT_VALUE_NOT_SET;
+  private Expression defaultValue = Column.DEFAULT_VALUE_NOT_SET;
 
   /** Default constructor for Jackson. */
   private FunctionParamDTO() {}
@@ -63,14 +64,13 @@ public class FunctionParamDTO implements FunctionParam, 
RESTRequest {
    * @param name Parameter name.
    * @param dataType Parameter data type.
    * @param comment Optional parameter comment.
-   * @param defaultValue Default value; if null, {@link 
FunctionParam#DEFAULT_VALUE_NOT_SET} is
-   *     used.
+   * @param defaultValue Default value; if null, {@link 
Column#DEFAULT_VALUE_NOT_SET} is used.
    */
   public FunctionParamDTO(String name, Type dataType, String comment, 
Expression defaultValue) {
     this.name = name;
     this.dataType = dataType;
     this.comment = comment;
-    this.defaultValue = defaultValue == null ? 
FunctionParam.DEFAULT_VALUE_NOT_SET : defaultValue;
+    this.defaultValue = defaultValue == null ? Column.DEFAULT_VALUE_NOT_SET : 
defaultValue;
   }
 
   /** {@inheritDoc} */
diff --git 
a/common/src/main/java/org/apache/gravitino/dto/requests/FunctionUpdateRequest.java
 
b/common/src/main/java/org/apache/gravitino/dto/requests/FunctionUpdateRequest.java
index eb25afb5bc..9f877c777a 100644
--- 
a/common/src/main/java/org/apache/gravitino/dto/requests/FunctionUpdateRequest.java
+++ 
b/common/src/main/java/org/apache/gravitino/dto/requests/FunctionUpdateRequest.java
@@ -56,6 +56,7 @@ public interface FunctionUpdateRequest extends RESTRequest {
    */
   FunctionChange functionChange();
 
+  /** Request to update a function comment. */
   @Getter
   @EqualsAndHashCode
   @ToString
@@ -100,6 +101,7 @@ public interface FunctionUpdateRequest extends RESTRequest {
     }
   }
 
+  /** Request to replace all implementations of a function. */
   @Getter
   @EqualsAndHashCode
   @ToString
@@ -137,6 +139,7 @@ public interface FunctionUpdateRequest extends RESTRequest {
     }
   }
 
+  /** Request to add an implementation to a function. */
   @Getter
   @EqualsAndHashCode
   @ToString
diff --git 
a/common/src/main/java/org/apache/gravitino/dto/util/DTOConverters.java 
b/common/src/main/java/org/apache/gravitino/dto/util/DTOConverters.java
index 625f01fa99..79c111a561 100644
--- a/common/src/main/java/org/apache/gravitino/dto/util/DTOConverters.java
+++ b/common/src/main/java/org/apache/gravitino/dto/util/DTOConverters.java
@@ -97,6 +97,7 @@ import org.apache.gravitino.function.Function;
 import org.apache.gravitino.function.FunctionColumn;
 import org.apache.gravitino.function.FunctionImpl;
 import org.apache.gravitino.function.FunctionParam;
+import org.apache.gravitino.function.FunctionParams;
 import org.apache.gravitino.function.FunctionSignature;
 import org.apache.gravitino.job.JobTemplate;
 import org.apache.gravitino.job.ShellJobTemplate;
@@ -1217,7 +1218,17 @@ public class DTOConverters {
     if (ArrayUtils.isEmpty(paramDTOs)) {
       return new FunctionParam[0];
     }
-    return 
Arrays.stream(paramDTOs).map(FunctionParam.class::cast).toArray(FunctionParam[]::new);
+    return Arrays.stream(paramDTOs)
+        .map(
+            p ->
+                p.defaultValue().equals(Column.DEFAULT_VALUE_NOT_SET)
+                    ? p
+                    : FunctionParams.of(
+                        p.name(),
+                        p.dataType(),
+                        p.comment(),
+                        fromFunctionArg((FunctionArg) p.defaultValue())))
+        .toArray(FunctionParam[]::new);
   }
 
   /**
diff --git a/rfc/Design of Functions Management in Gravitino.md b/rfc/Design of 
Functions Management in Gravitino.md
index fd8be858fb..291cffb55c 100644
--- a/rfc/Design of Functions Management in Gravitino.md        
+++ b/rfc/Design of Functions Management in Gravitino.md        
@@ -1,3 +1,22 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
 # Design of Functions Management in Gravitino
 
 # Background
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/rest/FunctionOperations.java
 
b/server/src/main/java/org/apache/gravitino/server/web/rest/FunctionOperations.java
index 897b53dbd1..afcef10710 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/rest/FunctionOperations.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/rest/FunctionOperations.java
@@ -21,9 +21,9 @@ package org.apache.gravitino.server.web.rest;
 import com.codahale.metrics.annotation.ResponseMetered;
 import com.codahale.metrics.annotation.Timed;
 import com.google.common.base.Preconditions;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import javax.inject.Inject;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
@@ -104,13 +104,13 @@ public class FunctionOperations {
               return Utils.ok(new EntityListResponse(identifiers));
             }
 
-            List<FunctionDTO> functionDTOs = new ArrayList<>();
-            for (NameIdentifier ident : identifiers) {
-              Function[] functions = functionDispatcher.getFunction(ident);
-              if (functions != null) {
-                
functionDTOs.addAll(Arrays.stream(functions).map(DTOConverters::toDTO).toList());
-              }
-            }
+            Function[] functions = 
functionDispatcher.listFunctionInfos(namespace);
+            functions = functions == null ? new Function[0] : functions;
+            List<FunctionDTO> functionDTOs =
+                Arrays.stream(functions)
+                    .filter(Objects::nonNull)
+                    .map(DTOConverters::toDTO)
+                    .toList();
             LOG.info(
                 "List {} function definitions under schema: {}.{}.{}",
                 functionDTOs.size(),

Reply via email to