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