This is an automated email from the ASF dual-hosted git repository. lpinter pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push: new 723d5227048 HIVE-26380: Fix NPE when reading a struct field with null value from iceberg table (#3426) (Laszlo Pinter, reviewed by Adam Szita) 723d5227048 is described below commit 723d52270488b8dbc108db1a9925d1c569415039 Author: László Pintér <47777102+lcspin...@users.noreply.github.com> AuthorDate: Tue Jul 12 15:15:48 2022 +0200 HIVE-26380: Fix NPE when reading a struct field with null value from iceberg table (#3426) (Laszlo Pinter, reviewed by Adam Szita) --- .../IcebergRecordObjectInspector.java | 6 ++++++ .../iceberg/mr/hive/TestHiveIcebergInserts.java | 24 ++++++++++++++++++++++ .../TestIcebergRecordObjectInspector.java | 10 +++++++++ 3 files changed, 40 insertions(+) diff --git a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/serde/objectinspector/IcebergRecordObjectInspector.java b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/serde/objectinspector/IcebergRecordObjectInspector.java index 1f56b4ce947..da5245bc779 100644 --- a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/serde/objectinspector/IcebergRecordObjectInspector.java +++ b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/serde/objectinspector/IcebergRecordObjectInspector.java @@ -72,11 +72,17 @@ public final class IcebergRecordObjectInspector extends StructObjectInspector { @Override public Object getStructFieldData(Object o, StructField structField) { + if (o == null) { + return null; + } return ((Record) o).get(((IcebergRecordStructField) structField).position()); } @Override public List<Object> getStructFieldsDataAsList(Object o) { + if (o == null) { + return null; + } Record record = (Record) o; return structFields .stream() diff --git a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergInserts.java b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergInserts.java index 7e3c72bf310..efb08c36d95 100644 --- a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergInserts.java +++ b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergInserts.java @@ -332,6 +332,30 @@ public class TestHiveIcebergInserts extends HiveIcebergStorageHandlerWithEngineB HiveIcebergTestUtils.validateData(target2, target2Records, 1); } + @Test + public void testStructMapWithNull() throws IOException { + Assume.assumeTrue("Vectorized parquet read throws class cast exception", + !(fileFormat == FileFormat.PARQUET && isVectorized)); + Schema schema = new Schema(required(1, "id", Types.LongType.get()), + required(2, "mapofstructs", Types.MapType.ofRequired(3, 4, Types.StringType.get(), + Types.StructType.of(required(5, "something", Types.StringType.get()), + required(6, "someone", Types.StringType.get()), + required(7, "somewhere", Types.StringType.get()) + )) + ) + ); + + List<Record> records = TestHelper.RecordsBuilder.newInstance(schema) + .add(0L, ImmutableMap.of()) + .build(); + + testTables.createTable(shell, "mapwithnull", schema, fileFormat, records); + + List<Object[]> results = shell.executeStatement("select mapofstructs['context'].someone FROM mapwithnull"); + Assert.assertEquals(1, results.size()); + Assert.assertNull(results.get(0)[0]); + } + @Test public void testWriteWithDefaultWriteFormat() { Assume.assumeTrue("Testing the default file format is enough for a single scenario.", diff --git a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/serde/objectinspector/TestIcebergRecordObjectInspector.java b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/serde/objectinspector/TestIcebergRecordObjectInspector.java index b67042b5eed..80a687f6f4a 100644 --- a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/serde/objectinspector/TestIcebergRecordObjectInspector.java +++ b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/serde/objectinspector/TestIcebergRecordObjectInspector.java @@ -61,4 +61,14 @@ public class TestIcebergRecordObjectInspector { Assert.assertEquals(innerRecord.get(0), innerSoi.getStructFieldData(innerData, stringField)); } + @Test + public void testIcebergRecordObjectInspectorWithRowNull() { + Schema schema = new Schema(required(1, "integer_field", Types.IntegerType.get()), + required(2, "struct_field", Types.StructType.of(Types.NestedField.required(3, "string_field", + Types.StringType.get())))); + StructObjectInspector soi = (StructObjectInspector) IcebergObjectInspector.create(schema); + Assert.assertNull(soi.getStructFieldsDataAsList(null)); + StructField integerField = soi.getStructFieldRef("integer_field"); + Assert.assertNull(soi.getStructFieldData(null, integerField)); + } }