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 106f98b160 [#7332] feat(api): Support statistic interfaces (#7333)
106f98b160 is described below

commit 106f98b1600145cc826196d0b1f06ebedf95ae8d
Author: roryqi <[email protected]>
AuthorDate: Wed Jul 2 10:57:25 2025 +0800

    [#7332] feat(api): Support statistic interfaces (#7333)
    
    ### What changes were proposed in this pull request?
    
    Support statistic interfaces
    
    ### Why are the changes needed?
    
    Fix: #7332
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes, I will add the document
    
    ### How was this patch tested?
    
    Code review
---
 .../exceptions/IllegalStatisticNameException.java  |  49 +++
 .../exceptions/UnmodifiableStatisticException.java |  49 +++
 .../java/org/apache/gravitino/stats/Statistic.java |  66 ++++
 .../org/apache/gravitino/stats/StatisticValue.java |  39 +++
 .../apache/gravitino/stats/StatisticValues.java    | 331 +++++++++++++++++++++
 .../apache/gravitino/stats/SupportsStatistics.java |  62 ++++
 .../apache/gravitino/stats/TestStatisticValue.java |  69 +++++
 7 files changed, 665 insertions(+)

diff --git 
a/api/src/main/java/org/apache/gravitino/exceptions/IllegalStatisticNameException.java
 
b/api/src/main/java/org/apache/gravitino/exceptions/IllegalStatisticNameException.java
new file mode 100644
index 0000000000..ee98b84036
--- /dev/null
+++ 
b/api/src/main/java/org/apache/gravitino/exceptions/IllegalStatisticNameException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** An exception thrown when statistic has an illegal name */
+public class IllegalStatisticNameException extends GravitinoRuntimeException {
+  /**
+   * Constructs a new exception with the specified detail message.
+   *
+   * @param message the detail message.
+   * @param args the arguments to the message.
+   */
+  @FormatMethod
+  public IllegalStatisticNameException(@FormatString String message, Object... 
args) {
+    super(message, args);
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message and cause.
+   *
+   * @param cause the cause.
+   * @param message the detail message.
+   * @param args the arguments to the message.
+   */
+  @FormatMethod
+  public IllegalStatisticNameException(
+      Throwable cause, @FormatString String message, Object... args) {
+    super(cause, message, args);
+  }
+}
diff --git 
a/api/src/main/java/org/apache/gravitino/exceptions/UnmodifiableStatisticException.java
 
b/api/src/main/java/org/apache/gravitino/exceptions/UnmodifiableStatisticException.java
new file mode 100644
index 0000000000..1130669b1a
--- /dev/null
+++ 
b/api/src/main/java/org/apache/gravitino/exceptions/UnmodifiableStatisticException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** An exception thrown when users modify an unmodifiable statistic */
+public class UnmodifiableStatisticException extends GravitinoRuntimeException {
+  /**
+   * Constructs a new exception with the specified detail message.
+   *
+   * @param message the detail message.
+   * @param args the arguments to the message.
+   */
+  @FormatMethod
+  public UnmodifiableStatisticException(@FormatString String message, 
Object... args) {
+    super(message, args);
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message and cause.
+   *
+   * @param cause the cause.
+   * @param message the detail message.
+   * @param args the arguments to the message.
+   */
+  @FormatMethod
+  public UnmodifiableStatisticException(
+      Throwable cause, @FormatString String message, Object... args) {
+    super(cause, message, args);
+  }
+}
diff --git a/api/src/main/java/org/apache/gravitino/stats/Statistic.java 
b/api/src/main/java/org/apache/gravitino/stats/Statistic.java
new file mode 100644
index 0000000000..ad10cb5b4c
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/stats/Statistic.java
@@ -0,0 +1,66 @@
+/*
+ * 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.stats;
+
+import java.util.Optional;
+import org.apache.gravitino.annotation.Evolving;
+
+/**
+ * Statistic interface represents a statistic that can be associated with a 
metadata object. It can
+ * be used to store various types of statistics, for example, table 
statistics, partition
+ * statistics, fileset statistics, etc.
+ */
+@Evolving
+public interface Statistic {
+
+  /** The prefix for custom statistics. Custom statistics are user-defined 
statistics. */
+  String CUSTOM_PREFIX = "custom.";
+
+  /**
+   * Get the name of the statistic.
+   *
+   * @return The name of the statistic.
+   */
+  String name();
+
+  /**
+   * Get the value of the statistic. The value is optional. If the statistic 
is not set, the value
+   * will be empty.
+   *
+   * @return An optional containing the value of the statistic if it is set, 
otherwise empty.
+   */
+  Optional<StatisticValue<?>> value();
+
+  /**
+   * The statistic is predefined by Gravitino if the value is true. The 
statistic is defined by
+   * users if the value is false. For example, the statistic "row_count" is a 
reserved statistic, A
+   * custom statistic name must start with "custom." prefix to avoid name 
conflict with reserved
+   * statistics. Because Gravitino may add more reserved statistics in the 
future.
+   *
+   * @return The type of the statistic.
+   */
+  boolean reserved();
+
+  /**
+   * Whether the statistic is modifiable.
+   *
+   * @return If the statistic is modifiable, return true, otherwise false.
+   */
+  boolean modifiable();
+}
diff --git a/api/src/main/java/org/apache/gravitino/stats/StatisticValue.java 
b/api/src/main/java/org/apache/gravitino/stats/StatisticValue.java
new file mode 100644
index 0000000000..264f296884
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/stats/StatisticValue.java
@@ -0,0 +1,39 @@
+/*
+ * 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.stats;
+
+import org.apache.gravitino.rel.types.Type;
+
+/** An interface representing a statistic value. */
+public interface StatisticValue<T> {
+
+  /**
+   * Returns the value of the statistic.
+   *
+   * @return the value of the statistic
+   */
+  T value();
+
+  /**
+   * Returns the data type of the statistic value.
+   *
+   * @return the data type of the statistic value
+   */
+  Type dataType();
+}
diff --git a/api/src/main/java/org/apache/gravitino/stats/StatisticValues.java 
b/api/src/main/java/org/apache/gravitino/stats/StatisticValues.java
new file mode 100644
index 0000000000..c362cc117b
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/stats/StatisticValues.java
@@ -0,0 +1,331 @@
+/*
+ * 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.stats;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import org.apache.gravitino.rel.types.Type;
+import org.apache.gravitino.rel.types.Types;
+
+/** A class representing a collection of statistic values. */
+public class StatisticValues {
+
+  private StatisticValues() {}
+
+  /**
+   * Creates a statistic value that holds a boolean value.
+   *
+   * @param value the boolean value to be held by this statistic value
+   * @return a BooleanValue instance containing the provided boolean value
+   */
+  public static BooleanValue booleanValue(boolean value) {
+    return new BooleanValue(value);
+  }
+
+  /**
+   * Creates a statistic value that holds a long value.
+   *
+   * @param value the long value to be held by this statistic value
+   * @return a LongValue instance containing the provided long value
+   */
+  public static LongValue longValue(long value) {
+    return new LongValue(value);
+  }
+
+  /**
+   * Creates a statistic value that holds a double value.
+   *
+   * @param value the double value to be held by this statistic value
+   * @return a DoubleValue instance containing the provided double value
+   */
+  public static DoubleValue doubleValue(double value) {
+    return new DoubleValue(value);
+  }
+
+  /**
+   * Creates a statistic value that holds a string value.
+   *
+   * @param value the string value to be held by this statistic value
+   * @return a StringValue instance containing the provided string value
+   */
+  public static StringValue stringValue(String value) {
+    return new StringValue(value);
+  }
+
+  /**
+   * Creates a statistic value that holds a list of other statistic values.
+   *
+   * @param <T> the type of the values in the list
+   * @param values the list of statistic values to be held by this statistic 
value
+   * @return a ListValue instance containing the provided list of statistic 
values
+   */
+  public static <T> ListValue<T> listValue(List<StatisticValue<T>> values) {
+    return new ListValue<T>(values);
+  }
+
+  /**
+   * Creates a statistic value that holds a map of string keys to other 
statistic values.
+   *
+   * @param values the map of string keys to statistic values to be held by 
this statistic value
+   * @return an ObjectValue instance containing the provided map of statistic 
values
+   */
+  public static ObjectValue objectValue(Map<String, StatisticValue<?>> values) 
{
+    return new ObjectValue(values);
+  }
+
+  /** A statistic value that holds a Boolean value. */
+  public static class BooleanValue implements StatisticValue<Boolean> {
+    private final Boolean value;
+
+    private BooleanValue(Boolean value) {
+      this.value = value;
+    }
+
+    @Override
+    public Boolean value() {
+      return value;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.BooleanType.get();
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hashCode(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof BooleanValue)) {
+        return false;
+      }
+
+      return Objects.equals(value, ((BooleanValue) obj).value());
+    }
+  }
+
+  /** A statistic value that holds a Long value. */
+  public static class LongValue implements StatisticValue<Long> {
+    private final Long value;
+
+    private LongValue(Long value) {
+      this.value = value;
+    }
+
+    @Override
+    public Long value() {
+      return value;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.LongType.get();
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof LongValue)) {
+        return false;
+      }
+
+      return Objects.equals(value, ((LongValue) obj).value());
+    }
+  }
+
+  /** A statistic value that holds a Double value. */
+  public static class DoubleValue implements StatisticValue<Double> {
+    private final Double value;
+
+    private DoubleValue(Double value) {
+      this.value = value;
+    }
+
+    @Override
+    public Double value() {
+      return value;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.DoubleType.get();
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof DoubleValue)) {
+        return false;
+      }
+
+      return Objects.equals(value, ((DoubleValue) obj).value());
+    }
+  }
+
+  /** A statistic value that holds a String value. */
+  public static class StringValue implements StatisticValue<String> {
+    private final String value;
+
+    private StringValue(String value) {
+      this.value = value;
+    }
+
+    @Override
+    public String value() {
+      return value;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.StringType.get();
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof StringValue)) {
+        return false;
+      }
+
+      return Objects.equals(value, ((StringValue) obj).value());
+    }
+  }
+
+  /** A statistic value that holds a List of other statistic values. */
+  public static class ListValue<T> implements 
StatisticValue<List<StatisticValue<T>>> {
+    private final List<StatisticValue<T>> valueList;
+
+    private ListValue(List<StatisticValue<T>> valueList) {
+      Preconditions.checkArgument(
+          valueList != null && !valueList.isEmpty(), "Values cannot be null or 
empty");
+
+      Type dataType = valueList.get(0).dataType();
+      Preconditions.checkArgument(
+          valueList.stream().allMatch(value -> 
value.dataType().equals(dataType)),
+          "All values in the list must have the same data type");
+
+      this.valueList = valueList;
+    }
+
+    @Override
+    public List<StatisticValue<T>> value() {
+      return valueList;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.ListType.nullable(valueList.get(0).dataType());
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(valueList);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof ListValue)) {
+        return false;
+      }
+
+      return Objects.equals(valueList, ((ListValue<?>) obj).value());
+    }
+  }
+
+  /** A statistic value that holds a Map of String keys to other statistic 
values. */
+  public static class ObjectValue implements StatisticValue<Map<String, 
StatisticValue<?>>> {
+    private final Map<String, StatisticValue<?>> valueMap;
+
+    private ObjectValue(Map<String, StatisticValue<?>> valueMap) {
+      Preconditions.checkArgument(
+          valueMap != null && !valueMap.isEmpty(), "Values cannot be null or 
empty");
+      this.valueMap = valueMap;
+    }
+
+    @Override
+    public Map<String, StatisticValue<?>> value() {
+      return valueMap;
+    }
+
+    @Override
+    public Type dataType() {
+      return Types.StructType.of(
+          valueMap.entrySet().stream()
+              .map(
+                  entry ->
+                      Types.StructType.Field.nullableField(
+                          entry.getKey(), entry.getValue().dataType()))
+              .toArray(Types.StructType.Field[]::new));
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(valueMap);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+
+      if (!(obj instanceof ObjectValue)) {
+        return false;
+      }
+
+      return Objects.equals(valueMap, ((ObjectValue) obj).value());
+    }
+  }
+}
diff --git 
a/api/src/main/java/org/apache/gravitino/stats/SupportsStatistics.java 
b/api/src/main/java/org/apache/gravitino/stats/SupportsStatistics.java
new file mode 100644
index 0000000000..dd8fa8a553
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/stats/SupportsStatistics.java
@@ -0,0 +1,62 @@
+/*
+ * 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.stats;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.exceptions.IllegalStatisticNameException;
+import org.apache.gravitino.exceptions.UnmodifiableStatisticException;
+
+/**
+ * SupportsStatistics provides methods to list and update statistics. A table, 
a partition or a
+ * fileset can implement this interface to manage its statistics.
+ */
+@Evolving
+public interface SupportsStatistics {
+
+  /**
+   * Lists all statistics.
+   *
+   * @return a list of statistics
+   */
+  List<Statistic> listStatistics();
+
+  /**
+   * Updates statistics with the provided values. If the statistic exists, it 
will be updated with
+   * the new value. If the statistic does not exist, it will be created. If 
the statistic is
+   * unmodifiable, it will throw an UnmodifiableStatisticException. If the 
statistic name is
+   * illegal, it will throw an IllegalStatisticNameException.
+   *
+   * @param statistics a map of statistic names to their values
+   * @return a list of updated statistics
+   */
+  List<Statistic> updateStatistics(Map<String, StatisticValue<?>> statistics)
+      throws UnmodifiableStatisticException, IllegalStatisticNameException;
+
+  /**
+   * Drop statistics by their names. If the statistic is unmodifiable, it will 
throw an
+   * UnmodifiableStatisticException.
+   *
+   * @param statistics a list of statistic names to be dropped
+   * @return true if the statistics were successfully dropped, false if no 
statistics were dropped
+   * @throws UnmodifiableStatisticException if any of the statistics to be 
dropped are unmodifiable
+   */
+  boolean dropStatistics(List<String> statistics) throws 
UnmodifiableStatisticException;
+}
diff --git 
a/api/src/test/java/org/apache/gravitino/stats/TestStatisticValue.java 
b/api/src/test/java/org/apache/gravitino/stats/TestStatisticValue.java
new file mode 100644
index 0000000000..9c1af7d2f9
--- /dev/null
+++ b/api/src/test/java/org/apache/gravitino/stats/TestStatisticValue.java
@@ -0,0 +1,69 @@
+/*
+ * 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.stats;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+import org.apache.gravitino.rel.types.Types;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestStatisticValue {
+
+  @Test
+  public void testLiterals() {
+    StatisticValues.BooleanValue booleanValue = 
StatisticValues.booleanValue(true);
+    Assertions.assertTrue(booleanValue.value());
+    Assertions.assertEquals(booleanValue.dataType(), Types.BooleanType.get());
+
+    StatisticValues.LongValue longValue = StatisticValues.longValue(100L);
+    Assertions.assertEquals(longValue.value(), 100L);
+    Assertions.assertEquals(longValue.dataType(), Types.LongType.get());
+
+    StatisticValues.DoubleValue doubleValue = 
StatisticValues.doubleValue(99.99);
+    Assertions.assertEquals(doubleValue.value(), 99.99);
+    Assertions.assertEquals(doubleValue.dataType(), Types.DoubleType.get());
+
+    StatisticValues.StringValue stringValue = 
StatisticValues.stringValue("test");
+    Assertions.assertEquals("test", stringValue.value());
+    Assertions.assertEquals(stringValue.dataType(), Types.StringType.get());
+
+    List<StatisticValue<String>> list =
+        Lists.newArrayList(StatisticValues.stringValue("a"), 
StatisticValues.stringValue("b"));
+    StatisticValues.ListValue<String> listValue = 
StatisticValues.listValue(list);
+    Assertions.assertEquals(2, listValue.value().size());
+    Assertions.assertEquals(listValue.dataType(), 
Types.ListType.nullable(Types.StringType.get()));
+    Assertions.assertIterableEquals(list, listValue.value());
+
+    Map<String, StatisticValue<?>> map = Maps.newHashMap();
+    map.put("a", StatisticValues.stringValue("a"));
+    map.put("b", StatisticValues.longValue(2L));
+    StatisticValues.ObjectValue objectValue = StatisticValues.objectValue(map);
+    Assertions.assertEquals(2, objectValue.value().size());
+    Assertions.assertEquals(map.get("a"), objectValue.value().get("a"));
+    Assertions.assertEquals(map.get("b"), objectValue.value().get("b"));
+    Assertions.assertEquals(
+        Types.StructType.of(
+            Types.StructType.Field.nullableField("a", Types.StringType.get()),
+            Types.StructType.Field.nullableField("b", Types.LongType.get())),
+        objectValue.dataType());
+  }
+}

Reply via email to