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

jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new bfca185a01 [#9528] feat(storage): support function management (PO) 
(part-1) (#9806)
bfca185a01 is described below

commit bfca185a0126a79e7c1b45b3afde0c34df9d3804
Author: mchades <[email protected]>
AuthorDate: Thu Jan 29 00:59:26 2026 +0800

    [#9528] feat(storage): support function management (PO) (part-1) (#9806)
    
    ### What changes were proposed in this pull request?
    
    Introduce PO (Persistent Object) classes for Function management in
    relational storage.
    - Added FunctionPO: Represents the base function metadata.
    - Added FunctionVersionPO: Represents specific versions of a function.
    - Added FunctionMaxVersionPO: Used for tracking function versions.
    
    ### Why are the changes needed?
    
    These POs serve as the fundamental data structures for mapping database
    records to Java objects in the relational storage implementation of UDFs
    (User Defined Functions).
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Compiling and verified in subsequent commits.
---
 GEMINI.md                                          |   1 +
 .../relational/po/FunctionMaxVersionPO.java        |  40 +++++
 .../storage/relational/po/FunctionPO.java          | 106 +++++++++++++
 .../storage/relational/po/FunctionVersionPO.java   |  85 ++++++++++
 .../storage/relational/po/TestFunctionPO.java      | 172 +++++++++++++++++++++
 5 files changed, 404 insertions(+)

diff --git a/GEMINI.md b/GEMINI.md
new file mode 120000
index 0000000000..47dc3e3d86
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionMaxVersionPO.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionMaxVersionPO.java
new file mode 100644
index 0000000000..b1eb8beee0
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionMaxVersionPO.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package org.apache.gravitino.storage.relational.po;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+@Getter
+@Accessors(fluent = true)
+@EqualsAndHashCode
+@ToString
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Builder(setterPrefix = "with")
+public class FunctionMaxVersionPO {
+  private Long functionId;
+  private Long version;
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionPO.java 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionPO.java
new file mode 100644
index 0000000000..35f7d00cf3
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionPO.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+package org.apache.gravitino.storage.relational.po;
+
+import com.google.common.base.Preconditions;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.StringUtils;
+
+@EqualsAndHashCode
+@Getter
+@ToString
+@Accessors(fluent = true)
+public class FunctionPO {
+
+  private Long functionId;
+
+  private String functionName;
+
+  private Long metalakeId;
+
+  private Long catalogId;
+
+  private Long schemaId;
+
+  private String functionType;
+
+  private Integer deterministic;
+
+  private String returnType;
+
+  private Integer functionLatestVersion;
+
+  private Integer functionCurrentVersion;
+
+  private String auditInfo;
+
+  private Long deletedAt;
+
+  private FunctionVersionPO functionVersionPO;
+
+  public FunctionPO() {}
+
+  @lombok.Builder(setterPrefix = "with")
+  private FunctionPO(
+      Long functionId,
+      String functionName,
+      Long metalakeId,
+      Long catalogId,
+      Long schemaId,
+      String functionType,
+      Integer deterministic,
+      String returnType,
+      Integer functionLatestVersion,
+      Integer functionCurrentVersion,
+      String auditInfo,
+      Long deletedAt,
+      FunctionVersionPO functionVersionPO) {
+    Preconditions.checkArgument(functionId != null, "Function id is required");
+    Preconditions.checkArgument(
+        StringUtils.isNotBlank(functionName), "Function name cannot be empty");
+    Preconditions.checkArgument(metalakeId != null, "Metalake id is required");
+    Preconditions.checkArgument(catalogId != null, "Catalog id is required");
+    Preconditions.checkArgument(schemaId != null, "Schema id is required");
+    Preconditions.checkArgument(
+        StringUtils.isNotBlank(functionType), "Function type cannot be empty");
+    Preconditions.checkArgument(
+        functionLatestVersion != null, "Function latest version is required");
+    Preconditions.checkArgument(
+        functionCurrentVersion != null, "Function current version is 
required");
+    Preconditions.checkArgument(StringUtils.isNotBlank(auditInfo), "Audit info 
cannot be empty");
+    Preconditions.checkArgument(deletedAt != null, "Deleted at is required");
+
+    this.functionId = functionId;
+    this.functionName = functionName;
+    this.metalakeId = metalakeId;
+    this.catalogId = catalogId;
+    this.schemaId = schemaId;
+    this.functionType = functionType;
+    this.deterministic = deterministic;
+    this.returnType = returnType;
+    this.functionLatestVersion = functionLatestVersion;
+    this.functionCurrentVersion = functionCurrentVersion;
+    this.auditInfo = auditInfo;
+    this.deletedAt = deletedAt;
+    this.functionVersionPO = functionVersionPO;
+  }
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionVersionPO.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionVersionPO.java
new file mode 100644
index 0000000000..410815f4cc
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/po/FunctionVersionPO.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+package org.apache.gravitino.storage.relational.po;
+
+import com.google.common.base.Preconditions;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.StringUtils;
+
+@EqualsAndHashCode
+@Getter
+@ToString
+@Accessors(fluent = true)
+public class FunctionVersionPO {
+
+  private Long id;
+
+  private Long functionId;
+
+  private Long metalakeId;
+
+  private Long catalogId;
+
+  private Long schemaId;
+
+  private Integer functionVersion;
+
+  private String functionComment;
+
+  private String definitions;
+
+  private String auditInfo;
+
+  private Long deletedAt;
+
+  public FunctionVersionPO() {}
+
+  @lombok.Builder(setterPrefix = "with")
+  private FunctionVersionPO(
+      Long id,
+      Long functionId,
+      Long metalakeId,
+      Long catalogId,
+      Long schemaId,
+      Integer functionVersion,
+      String functionComment,
+      String definitions,
+      String auditInfo,
+      Long deletedAt) {
+    Preconditions.checkArgument(functionId != null, "Function id is required");
+    Preconditions.checkArgument(functionVersion != null, "Function version is 
required");
+    Preconditions.checkArgument(StringUtils.isNotBlank(definitions), 
"Definitions cannot be empty");
+    Preconditions.checkArgument(StringUtils.isNotBlank(auditInfo), "Audit info 
cannot be empty");
+    Preconditions.checkArgument(deletedAt != null, "Deleted at is required");
+
+    this.id = id;
+    this.functionId = functionId;
+    this.metalakeId = metalakeId;
+    this.catalogId = catalogId;
+    this.schemaId = schemaId;
+    this.functionVersion = functionVersion;
+    this.functionComment = functionComment;
+    this.definitions = definitions;
+    this.auditInfo = auditInfo;
+    this.deletedAt = deletedAt;
+  }
+}
diff --git 
a/core/src/test/java/org/apache/gravitino/storage/relational/po/TestFunctionPO.java
 
b/core/src/test/java/org/apache/gravitino/storage/relational/po/TestFunctionPO.java
new file mode 100644
index 0000000000..a44c367e68
--- /dev/null
+++ 
b/core/src/test/java/org/apache/gravitino/storage/relational/po/TestFunctionPO.java
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+package org.apache.gravitino.storage.relational.po;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestFunctionPO {
+
+  @Test
+  public void testFunctionPOBuilder() {
+    FunctionPO functionPO =
+        FunctionPO.builder()
+            .withFunctionId(1L)
+            .withFunctionName("test-function")
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionType("SCALAR")
+            .withDeterministic(1)
+            .withReturnType("STRING")
+            .withFunctionLatestVersion(1)
+            .withFunctionCurrentVersion(1)
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    Assertions.assertEquals(1L, functionPO.functionId());
+    Assertions.assertEquals("test-function", functionPO.functionName());
+    Assertions.assertEquals(1L, functionPO.metalakeId());
+    Assertions.assertEquals(1L, functionPO.catalogId());
+    Assertions.assertEquals(1L, functionPO.schemaId());
+    Assertions.assertEquals("SCALAR", functionPO.functionType());
+    Assertions.assertEquals(1, functionPO.deterministic());
+    Assertions.assertEquals("STRING", functionPO.returnType());
+    Assertions.assertEquals(1, functionPO.functionLatestVersion());
+    Assertions.assertEquals(1, functionPO.functionCurrentVersion());
+    Assertions.assertEquals("audit-info", functionPO.auditInfo());
+    Assertions.assertEquals(0L, functionPO.deletedAt());
+  }
+
+  @Test
+  public void testFunctionVersionPOBuilder() {
+    FunctionVersionPO functionVersionPO =
+        FunctionVersionPO.builder()
+            .withId(1L)
+            .withFunctionId(1L)
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionVersion(1)
+            .withFunctionComment("test-comment")
+            .withDefinitions("definitions")
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    Assertions.assertEquals(1L, functionVersionPO.id());
+    Assertions.assertEquals(1L, functionVersionPO.functionId());
+    Assertions.assertEquals(1L, functionVersionPO.metalakeId());
+    Assertions.assertEquals(1L, functionVersionPO.catalogId());
+    Assertions.assertEquals(1L, functionVersionPO.schemaId());
+    Assertions.assertEquals(1, functionVersionPO.functionVersion());
+    Assertions.assertEquals("test-comment", 
functionVersionPO.functionComment());
+    Assertions.assertEquals("definitions", functionVersionPO.definitions());
+    Assertions.assertEquals("audit-info", functionVersionPO.auditInfo());
+    Assertions.assertEquals(0L, functionVersionPO.deletedAt());
+  }
+
+  @Test
+  public void testFunctionMaxVersionPOBuilder() {
+    FunctionMaxVersionPO functionMaxVersionPO =
+        
FunctionMaxVersionPO.builder().withFunctionId(1L).withVersion(1L).build();
+
+    Assertions.assertEquals(1L, functionMaxVersionPO.functionId());
+    Assertions.assertEquals(1L, functionMaxVersionPO.version());
+  }
+
+  @Test
+  public void testEqualsAndHashCode() {
+    FunctionPO functionPO1 =
+        FunctionPO.builder()
+            .withFunctionId(1L)
+            .withFunctionName("test-function")
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionType("SCALAR")
+            .withDeterministic(1)
+            .withReturnType("STRING")
+            .withFunctionLatestVersion(1)
+            .withFunctionCurrentVersion(1)
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    FunctionPO functionPO2 =
+        FunctionPO.builder()
+            .withFunctionId(1L)
+            .withFunctionName("test-function")
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionType("SCALAR")
+            .withDeterministic(1)
+            .withReturnType("STRING")
+            .withFunctionLatestVersion(1)
+            .withFunctionCurrentVersion(1)
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    Assertions.assertEquals(functionPO1, functionPO2);
+    Assertions.assertEquals(functionPO1.hashCode(), functionPO2.hashCode());
+
+    FunctionVersionPO functionVersionPO1 =
+        FunctionVersionPO.builder()
+            .withId(1L)
+            .withFunctionId(1L)
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionVersion(1)
+            .withFunctionComment("test-comment")
+            .withDefinitions("definitions")
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    FunctionVersionPO functionVersionPO2 =
+        FunctionVersionPO.builder()
+            .withId(1L)
+            .withFunctionId(1L)
+            .withMetalakeId(1L)
+            .withCatalogId(1L)
+            .withSchemaId(1L)
+            .withFunctionVersion(1)
+            .withFunctionComment("test-comment")
+            .withDefinitions("definitions")
+            .withAuditInfo("audit-info")
+            .withDeletedAt(0L)
+            .build();
+
+    Assertions.assertEquals(functionVersionPO1, functionVersionPO2);
+    Assertions.assertEquals(functionVersionPO1.hashCode(), 
functionVersionPO2.hashCode());
+
+    FunctionMaxVersionPO functionMaxVersionPO1 =
+        
FunctionMaxVersionPO.builder().withFunctionId(1L).withVersion(1L).build();
+
+    FunctionMaxVersionPO functionMaxVersionPO2 =
+        
FunctionMaxVersionPO.builder().withFunctionId(1L).withVersion(1L).build();
+
+    Assertions.assertEquals(functionMaxVersionPO1, functionMaxVersionPO2);
+    Assertions.assertEquals(functionMaxVersionPO1.hashCode(), 
functionMaxVersionPO2.hashCode());
+  }
+}

Reply via email to