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());
+ }
+}