This is an automated email from the ASF dual-hosted git repository.
mchades 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 40ab9a58f2 [#11983] test(iceberg): add end-to-end coverage for
round-trip of remaining V2 column types (#11984)
40ab9a58f2 is described below
commit 40ab9a58f2909f9c8f8c3c27f6ca510fc4ffbf8a
Author: Nevin Zheng <[email protected]>
AuthorDate: Tue Jul 14 03:25:44 2026 -0700
[#11983] test(iceberg): add end-to-end coverage for round-trip of remaining
V2 column types (#11984)
### What changes were proposed in this pull request?
Adds `testCreateAndLoadIcebergTableV2Types` to `CatalogIcebergBaseIT`.
It creates a table containing the V2 column types that were not
previously exercised end-to-end — `boolean`, `float`, `double`, `uuid`,
`fixed`, `binary`, `decimal`, `list`, `map` — through the native
metadata API, loads it back, and asserts that (a) the Gravitino types
round-trip unchanged and (b) the underlying Iceberg schema stores the
expected Iceberg types. Because these are all valid V2 types, the test
runs on both backends via the existing subclasses
(`CatalogIcebergRestIT`, `CatalogIcebergHiveIT`) with no assumptions.
### Why are the changes needed?
`CatalogIcebergBaseIT` only round-tripped a subset of V2 types through a
live backend (`int`, `long`, `date`, `string`, `struct`, `time`,
`timestamp`). The converter mappings for the remaining types are
unit-tested in `TestConvertUtil`, but were never verified through the
real REST/IRC and Hive backends — so backend/serialization regressions
for `decimal` (precision/scale), `fixed` (length), `list`, and `map` in
particular could slip through. This closes that gap.
Fix: #11983
### Does this PR introduce _any_ user-facing change?
No. Test-only.
### How was this patch tested?
This PR adds the test (`testCreateAndLoadIcebergTableV2Types`), and it
passes. Run locally on both backends via `-PskipTests
-PskipDockerTests=false`:
- `CatalogIcebergRestIT.testCreateAndLoadIcebergTableV2Types` — passed
(1 test, 0 failures).
- `CatalogIcebergHiveIT.testCreateAndLoadIcebergTableV2Types` — passed
(1 test, 0 failures).
---
.../integration/test/CatalogIcebergBaseIT.java | 80 ++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git
a/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/CatalogIcebergBaseIT.java
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/CatalogIcebergBaseIT.java
index d733ed701d..7b465f9cca 100644
---
a/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/CatalogIcebergBaseIT.java
+++
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/integration/test/CatalogIcebergBaseIT.java
@@ -633,6 +633,86 @@ public abstract class CatalogIcebergBaseIT extends BaseIT {
Assertions.assertEquals("col_2_comment",
icebergSchema.columns().get(1).doc());
}
+ @Test
+ void testCreateAndLoadIcebergTableV2Types() {
+ // End-to-end round-trip for the V2 types not otherwise exercised through
a live backend:
+ // boolean, float, double, uuid, fixed, binary, decimal, list and map. The
converter mappings
+ // themselves are unit-tested in TestConvertUtil; this test confirms they
survive create and
+ // load through the real backend. Every V2 type is valid on both the
REST/IRC and Hive backends,
+ // so this runs unconditionally under both subclasses of this base class.
+ Column[] columns =
+ new Column[] {
+ Column.of("c_boolean", Types.BooleanType.get(), "boolean col"),
+ Column.of("c_float", Types.FloatType.get(), "float col"),
+ Column.of("c_double", Types.DoubleType.get(), "double col"),
+ Column.of("c_uuid", Types.UUIDType.get(), "uuid col"),
+ Column.of("c_fixed", Types.FixedType.of(16), "fixed col"),
+ Column.of("c_binary", Types.BinaryType.get(), "binary col"),
+ Column.of("c_decimal", Types.DecimalType.of(10, 2), "decimal col"),
+ Column.of("c_list", Types.ListType.of(Types.IntegerType.get(),
false), "list col"),
+ Column.of(
+ "c_map",
+ Types.MapType.of(Types.StringType.get(),
Types.IntegerType.get(), false),
+ "map col")
+ };
+
+ NameIdentifier tableIdentifier =
+ NameIdentifier.of(schemaName,
GravitinoITUtils.genRandomName("v2_types_table"));
+ TableCatalog tableCatalog = catalog.asTableCatalog();
+
+ // Gravitino -> Iceberg: create through the native metadata API.
+ Table created =
+ tableCatalog.createTable(tableIdentifier, columns, table_comment,
createProperties());
+ Assertions.assertEquals(columns.length, created.columns().length);
+ for (int i = 0; i < columns.length; i++) {
+ assertColumn(columns[i], created.columns()[i]);
+ }
+
+ // Iceberg -> Gravitino: load back through the native metadata API and
confirm every type
+ // round-trips unchanged.
+ Table loaded = tableCatalog.loadTable(tableIdentifier);
+ Assertions.assertEquals(columns.length, loaded.columns().length);
+ for (int i = 0; i < columns.length; i++) {
+ assertColumn(columns[i], loaded.columns()[i]);
+ }
+
+ // Confirm the columns are stored as the expected Iceberg types in the
underlying table, not
+ // merely echoed back by Gravitino.
+ org.apache.iceberg.Schema storedSchema =
+ icebergCatalog
+
.loadTable(IcebergCatalogWrapperHelper.buildIcebergTableIdentifier(tableIdentifier))
+ .schema();
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.BooleanType.get(),
+ storedSchema.findField("c_boolean").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.FloatType.get(),
storedSchema.findField("c_float").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.DoubleType.get(),
storedSchema.findField("c_double").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.UUIDType.get(),
storedSchema.findField("c_uuid").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.FixedType.ofLength(16),
+ storedSchema.findField("c_fixed").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.BinaryType.get(),
storedSchema.findField("c_binary").type());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.DecimalType.of(10, 2),
+ storedSchema.findField("c_decimal").type());
+
+ org.apache.iceberg.types.Type listType =
storedSchema.findField("c_list").type();
+ Assertions.assertTrue(listType.isListType());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.IntegerType.get(),
listType.asListType().elementType());
+
+ org.apache.iceberg.types.Type mapType =
storedSchema.findField("c_map").type();
+ Assertions.assertTrue(mapType.isMapType());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.StringType.get(),
mapType.asMapType().keyType());
+ Assertions.assertEquals(
+ org.apache.iceberg.types.Types.IntegerType.get(),
mapType.asMapType().valueType());
+ }
+
@Test
void testV3TypeConversionViaIcebergClient() {
// REST-backend only. The Hive metastore in the current CI Hive image
cannot store Iceberg V3