public static ObjectInspector create(@Nullable Schema schema) {
    if (schema == null) {
      return IcebergRecordObjectInspector.empty();
    }

    return TypeUtil.visit(schema, new IcebergObjectInspector());
  }
@Test
  public void testIcebergObjectInspector() {
    ObjectInspector oi = IcebergObjectInspector.create(schema);
    Assert.assertNotNull(oi);
    Assert.assertEquals(ObjectInspector.Category.STRUCT, oi.getCategory());

    StructObjectInspector soi = (StructObjectInspector) oi;

    // binary
    StructField binaryField = soi.getStructFieldRef("binary_field");
    Assert.assertEquals(1, binaryField.getFieldID());
    Assert.assertEquals("binary_field", binaryField.getFieldName());
    Assert.assertEquals("binary comment", binaryField.getFieldComment());
    Assert.assertEquals(IcebergBinaryObjectInspector.get(), binaryField.getFieldObjectInspector());

    // boolean
    StructField booleanField = soi.getStructFieldRef("boolean_field");
    Assert.assertEquals(2, booleanField.getFieldID());
    Assert.assertEquals("boolean_field", booleanField.getFieldName());
    Assert.assertEquals("boolean comment", booleanField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(boolean.class), booleanField.getFieldObjectInspector());

    // date
    StructField dateField = soi.getStructFieldRef("date_field");
    Assert.assertEquals(3, dateField.getFieldID());
    Assert.assertEquals("date_field", dateField.getFieldName());
    Assert.assertEquals("date comment", dateField.getFieldComment());
    if (HiveVersion.min(HiveVersion.HIVE_3)) {
      Assert.assertEquals(
          "org.apache.iceberg.mr.hive.serde.objectinspector.IcebergDateObjectInspectorHive3",
          dateField.getFieldObjectInspector().getClass().getName());
    } else {
      Assert.assertEquals(
          "org.apache.iceberg.mr.hive.serde.objectinspector.IcebergDateObjectInspector",
          dateField.getFieldObjectInspector().getClass().getName());
    }

    // decimal
    StructField decimalField = soi.getStructFieldRef("decimal_field");
    Assert.assertEquals(4, decimalField.getFieldID());
    Assert.assertEquals("decimal_field", decimalField.getFieldName());
    Assert.assertEquals("decimal comment", decimalField.getFieldComment());
    Assert.assertEquals(IcebergDecimalObjectInspector.get(38, 18), decimalField.getFieldObjectInspector());

    // double
    StructField doubleField = soi.getStructFieldRef("double_field");
    Assert.assertEquals(5, doubleField.getFieldID());
    Assert.assertEquals("double_field", doubleField.getFieldName());
    Assert.assertEquals("double comment", doubleField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(double.class), doubleField.getFieldObjectInspector());

    // fixed
    StructField fixedField = soi.getStructFieldRef("fixed_field");
    Assert.assertEquals(6, fixedField.getFieldID());
    Assert.assertEquals("fixed_field", fixedField.getFieldName());
    Assert.assertEquals("fixed comment", fixedField.getFieldComment());
    Assert.assertEquals(IcebergFixedObjectInspector.get(), fixedField.getFieldObjectInspector());

    // float
    StructField floatField = soi.getStructFieldRef("float_field");
    Assert.assertEquals(7, floatField.getFieldID());
    Assert.assertEquals("float_field", floatField.getFieldName());
    Assert.assertEquals("float comment", floatField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(float.class), floatField.getFieldObjectInspector());

    // integer
    StructField integerField = soi.getStructFieldRef("integer_field");
    Assert.assertEquals(8, integerField.getFieldID());
    Assert.assertEquals("integer_field", integerField.getFieldName());
    Assert.assertEquals("integer comment", integerField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(int.class), integerField.getFieldObjectInspector());

    // long
    StructField longField = soi.getStructFieldRef("long_field");
    Assert.assertEquals(9, longField.getFieldID());
    Assert.assertEquals("long_field", longField.getFieldName());
    Assert.assertEquals("long comment", longField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(long.class), longField.getFieldObjectInspector());

    // string
    StructField stringField = soi.getStructFieldRef("string_field");
    Assert.assertEquals(10, stringField.getFieldID());
    Assert.assertEquals("string_field", stringField.getFieldName());
    Assert.assertEquals("string comment", stringField.getFieldComment());
    Assert.assertEquals(getPrimitiveObjectInspector(String.class), stringField.getFieldObjectInspector());

    // timestamp without tz
    StructField timestampField = soi.getStructFieldRef("timestamp_field");
    Assert.assertEquals(11, timestampField.getFieldID());
    Assert.assertEquals("timestamp_field", timestampField.getFieldName());
    Assert.assertEquals("timestamp comment", timestampField.getFieldComment());
    Assert.assertEquals(IcebergTimestampObjectInspectorHive3.get(), timestampField.getFieldObjectInspector());

    // timestamp with tz
    StructField timestampTzField = soi.getStructFieldRef("timestamptz_field");
    Assert.assertEquals(12, timestampTzField.getFieldID());
    Assert.assertEquals("timestamptz_field", timestampTzField.getFieldName());
    Assert.assertEquals("timestamptz comment", timestampTzField.getFieldComment());
    Assert.assertEquals(IcebergTimestampWithZoneObjectInspectorHive3.get(), timestampTzField.getFieldObjectInspector());

    // UUID
    StructField uuidField = soi.getStructFieldRef("uuid_field");
    Assert.assertEquals(13, uuidField.getFieldID());
    Assert.assertEquals("uuid_field", uuidField.getFieldName());
    Assert.assertEquals("uuid comment", uuidField.getFieldComment());
    Assert.assertEquals(IcebergUUIDObjectInspector.get(), uuidField.getFieldObjectInspector());

    // list
    StructField listField = soi.getStructFieldRef("list_field");
    Assert.assertEquals(14, listField.getFieldID());
    Assert.assertEquals("list_field", listField.getFieldName());
    Assert.assertEquals("list comment", listField.getFieldComment());
    Assert.assertEquals(getListObjectInspector(String.class), listField.getFieldObjectInspector());

    // map
    StructField mapField = soi.getStructFieldRef("map_field");
    Assert.assertEquals(16, mapField.getFieldID());
    Assert.assertEquals("map_field", mapField.getFieldName());
    Assert.assertEquals("map comment", mapField.getFieldComment());
    Assert.assertEquals(getMapObjectInspector(String.class, int.class), mapField.getFieldObjectInspector());

    // struct
    StructField structField = soi.getStructFieldRef("struct_field");
    Assert.assertEquals(19, structField.getFieldID());
    Assert.assertEquals("struct_field", structField.getFieldName());
    Assert.assertEquals("struct comment", structField.getFieldComment());

    ObjectInspector expectedObjectInspector = new IcebergRecordObjectInspector(
            (Types.StructType) schema.findType(19), ImmutableList.of(getPrimitiveObjectInspector(String.class)));
    Assert.assertEquals(expectedObjectInspector, structField.getFieldObjectInspector());

    // time
    StructField timeField = soi.getStructFieldRef("time_field");
    Assert.assertEquals(21, timeField.getFieldID());
    Assert.assertEquals("time_field", timeField.getFieldName());
    Assert.assertEquals("time comment", timeField.getFieldComment());
    Assert.assertEquals(IcebergTimeObjectInspector.get(), timeField.getFieldObjectInspector());
  }