rdblue commented on a change in pull request #1607:
URL: https://github.com/apache/iceberg/pull/1607#discussion_r528930108



##########
File path: 
mr/src/test/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandlerBaseTest.java
##########
@@ -581,6 +582,262 @@ public void testCreateTableAboveExistingTable() throws 
TException, IOException,
     }
   }
 
+  @Test
+  public void testArrayOfPrimitivesInTable() throws IOException {
+    Schema schema =
+            new Schema(required(1, "arrayofprimitives", 
Types.ListType.ofRequired(2, Types.IntegerType.get())));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"arraytable");
+    // access a single element from the array
+    for (int i = 0; i < records.size(); i++) {
+      List<?> expectedList = (List<?>) 
records.get(i).getField("arrayofprimitives");
+      for (int j = 0; j < expectedList.size(); j++) {
+        List<Object[]> queryResult = shell.executeStatement(
+                String.format("SELECT arrayofprimitives[%d] FROM 
default.arraytable " + "LIMIT 1 OFFSET %d", j, i));
+        Assert.assertEquals(expectedList.get(j), queryResult.get(0)[0]);
+      }
+    }
+  }
+
+  @Test
+  public void testArrayOfArraysInTable() throws IOException {
+    Schema schema =
+            new Schema(
+                    required(1, "arrayofarrays",
+                            Types.ListType.ofRequired(2, 
Types.ListType.ofRequired(3, Types.DateType.get()))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"arraytable");
+    // access an element from a matrix
+    for (int i = 0; i < records.size(); i++) {
+      List<?> expectedList = (List<?>) 
records.get(i).getField("arrayofarrays");
+      for (int j = 0; j < expectedList.size(); j++) {
+        List<?> expectedInnerList = (List<?>) expectedList.get(j);
+        for (int k = 0; k < expectedInnerList.size(); k++) {
+          List<Object[]> queryResult = shell.executeStatement(
+                  String.format("SELECT arrayofarrays[%d][%d] FROM 
default.arraytable " + "LIMIT 1 OFFSET %d",
+                          j, k, i));
+          Assert.assertEquals(expectedInnerList.get(k).toString(), 
queryResult.get(0)[0]);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void testArrayOfMapsInTable() throws IOException {
+    Schema schema =
+            new Schema(required(1, "arrayofmaps", Types.ListType
+                    .ofRequired(2, Types.MapType.ofRequired(3, 4, 
Types.StringType.get(),
+                            Types.BooleanType.get()))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"arraytable");
+    // access an element from a map in an array
+    for (int i = 0; i < records.size(); i++) {
+      List<?> expectedList = (List<?>) records.get(i).getField("arrayofmaps");
+      for (int j = 0; j < expectedList.size(); j++) {
+        Map<?, ?> expectedMap = (Map<?, ?>) expectedList.get(j);
+        for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+          List<Object[]> queryResult = shell.executeStatement(String
+                  .format("SELECT arrayofmaps[%d][\"%s\"] FROM 
default.arraytable LIMIT 1 OFFSET %d", j,
+                          entry.getKey(), i));
+          Assert.assertEquals(entry.getValue(), queryResult.get(0)[0]);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void testArrayOfStructsInTable() throws IOException {
+    Schema schema =
+            new Schema(
+                    required(1, "arrayofstructs", Types.ListType.ofRequired(2, 
Types.StructType
+                            .of(required(3, "something", 
Types.DoubleType.get()), required(4, "someone",
+                                    Types.LongType.get()), required(5, 
"somewhere", Types.StringType.get())))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"arraytable");
+    // access an element from a struct in an array
+    for (int i = 0; i < records.size(); i++) {
+      List<?> expectedList = (List<?>) 
records.get(i).getField("arrayofstructs");
+      for (int j = 0; j < expectedList.size(); j++) {
+        List<Object[]> queryResult = 
shell.executeStatement(String.format("SELECT arrayofstructs[%d].something, " +
+                "arrayofstructs[%d].someone, arrayofstructs[%d].somewhere FROM 
default.arraytable LIMIT 1 " +
+                "OFFSET %d", j, j, j, i));
+        GenericRecord genericRecord = (GenericRecord) expectedList.get(j);
+        Assert.assertEquals(genericRecord.getField("something"), 
queryResult.get(0)[0]);
+        Assert.assertEquals(genericRecord.getField("someone"), 
queryResult.get(0)[1]);
+        Assert.assertEquals(genericRecord.getField("somewhere"), 
queryResult.get(0)[2]);
+      }
+    }
+  }
+
+  @Test
+  public void testMapOfPrimitivesInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "mapofprimitives", Types.MapType.ofRequired(2, 3, 
Types.StringType.get(),
+                    Types.IntegerType.get())));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"maptable");
+    // access a single value from the map
+    for (int i = 0; i < records.size(); i++) {
+      Map<?, ?> expectedMap = (Map<?, ?>) 
records.get(i).getField("mapofprimitives");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        List<Object[]> queryResult = shell.executeStatement(String
+                .format("SELECT mapofprimitives[\"%s\"] " + "FROM 
default.maptable LIMIT 1 OFFSET %d", entry.getKey(),
+                        i));
+        Assert.assertEquals(entry.getValue(), queryResult.get(0)[0]);
+      }
+    }
+  }
+
+  @Test
+  public void testMapOfArraysInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "mapofarrays",
+                    Types.MapType.ofRequired(2, 3, Types.StringType.get(), 
Types.ListType.ofRequired(4,
+                            Types.DateType.get()))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"maptable");
+    // access a single element from a list in a map
+    for (int i = 0; i < records.size(); i++) {
+      Map<?, ?> expectedMap = (Map<?, ?>) 
records.get(i).getField("mapofarrays");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        List<?> expectedList = (List<?>) entry.getValue();
+        for (int j = 0; j < expectedList.size(); j++) {
+          List<Object[]> queryResult = shell.executeStatement(String
+                  .format("SELECT mapofarrays[\"%s\"]" + "[%d] FROM maptable 
LIMIT 1 OFFSET %d", entry.getKey(), j, i));
+          Assert.assertEquals(expectedList.get(j).toString(), 
queryResult.get(0)[0]);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void testMapOfMapsInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "mapofmaps", Types.MapType.ofRequired(2, 3, 
Types.StringType.get(),
+                    Types.MapType.ofRequired(4, 5, Types.StringType.get(), 
Types.StringType.get()))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"maptable");
+    // access a single element from a map in a map
+    for (int i = 0; i < records.size(); i++) {
+      Map<?, ?> expectedMap = (Map<?, ?>) records.get(i).getField("mapofmaps");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        Map<?, ?> expectedInnerMap = (Map<?, ?>) entry.getValue();
+        for (Map.Entry<?, ?> innerEntry : expectedInnerMap.entrySet()) {
+          List<Object[]> queryResult = shell.executeStatement(String
+                  .format("SELECT mapofmaps[\"%s\"]" + "[\"%s\"] FROM maptable 
LIMIT 1 OFFSET %d", entry.getKey(),
+                          innerEntry.getKey(), i));
+          Assert.assertEquals(innerEntry.getValue(), queryResult.get(0)[0]);
+        }
+      }
+    }
+  }
+
+  @Test
+  public void testMapOfStructsInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "mapofstructs", Types.MapType.ofRequired(2, 3, 
Types.StringType.get(),
+                    Types.StructType.of(required(4, "something", 
Types.DoubleType.get()),
+                            required(5, "someone", Types.LongType.get()),
+                            required(6, "somewhere", 
Types.StringType.get())))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"maptable");
+    // access a single element from a struct in a map
+    for (int i = 0; i < records.size(); i++) {
+      Map<?, ?> expectedMap = (Map<?, ?>) 
records.get(i).getField("mapofstructs");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        List<Object[]> queryResult = 
shell.executeStatement(String.format("SELECT mapofstructs[\"%s\"].something, " +
+                "mapofstructs[\"%s\"].someone, mapofstructs[\"%s\"].somewhere 
FROM default.maptable LIMIT 1 " +
+                "OFFSET %d", entry.getKey(), entry.getKey(), entry.getKey(), 
i));
+        GenericRecord genericRecord = (GenericRecord) entry.getValue();
+        Assert.assertEquals(genericRecord.getField("something"), 
queryResult.get(0)[0]);
+        Assert.assertEquals(genericRecord.getField("someone"), 
queryResult.get(0)[1]);
+        Assert.assertEquals(genericRecord.getField("somewhere"), 
queryResult.get(0)[2]);
+      }
+    }
+  }
+
+  @Test
+  public void testStructOfPrimitivesInTable() throws IOException {
+    Schema schema = new Schema(required(1, "structofprimitives",
+            Types.StructType.of(required(2, "key", Types.StringType.get()), 
required(3, "value",
+                    Types.IntegerType.get()))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"structtable");
+    // access a single value in a struct
+    for (int i = 0; i < records.size(); i++) {
+      GenericRecord expectedStruct = (GenericRecord) 
records.get(i).getField("structofprimitives");
+      List<Object[]> queryResult = shell.executeStatement(String.format(
+              "SELECT structofprimitives.key, structofprimitives.value FROM 
default.structtable LIMIT 1 OFFSET %d", i));
+      Assert.assertEquals(expectedStruct.getField("key"), 
queryResult.get(0)[0]);
+      Assert.assertEquals(expectedStruct.getField("value"), 
queryResult.get(0)[1]);
+    }
+  }
+
+  @Test
+  public void testStructOfArraysInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "structofarrays", Types.StructType
+                    .of(required(2, "names", Types.ListType.ofRequired(3, 
Types.StringType.get())),
+                            required(4, "birthdays", 
Types.ListType.ofRequired(5,
+                                    Types.DateType.get())))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"structtable");
+    // access an element of an array inside a struct
+    for (int i = 0; i < records.size(); i++) {
+      GenericRecord expectedStruct = (GenericRecord) 
records.get(i).getField("structofarrays");
+      List<?> expectedList = (List<?>) expectedStruct.getField("names");
+      for (int j = 0; j < expectedList.size(); j++) {
+        List<Object[]> queryResult = shell.executeStatement(
+                String.format("SELECT structofarrays.names[%d] FROM 
default.structtable LIMIT 1 OFFSET %d", j, i));
+        Assert.assertEquals(expectedList.get(j), queryResult.get(0)[0]);
+      }
+      expectedList = (List<?>) expectedStruct.getField("birthdays");
+      for (int j = 0; j < expectedList.size(); j++) {
+        List<Object[]> queryResult = shell.executeStatement(
+                String.format("SELECT structofarrays.birthdays[%d] FROM 
default.structtable LIMIT 1 OFFSET %d", j, i));
+        Assert.assertEquals(expectedList.get(j).toString(), 
queryResult.get(0)[0]);
+      }
+    }
+  }
+
+  @Test
+  public void testStructOfMapsInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "structofmaps", Types.StructType
+                    .of(required(2, "map1", Types.MapType.ofRequired(3, 4,
+                            Types.StringType.get(), Types.StringType.get())), 
required(5, "map2",
+                            Types.MapType.ofRequired(6, 7, 
Types.StringType.get(),
+                                    Types.IntegerType.get())))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"structtable");
+    // access a map entry inside a struct
+    for (int i = 0; i < records.size(); i++) {
+      GenericRecord expectedStruct = (GenericRecord) 
records.get(i).getField("structofmaps");
+      Map<?, ?> expectedMap = (Map<?, ?>) expectedStruct.getField("map1");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        List<Object[]> queryResult = shell.executeStatement(String
+                .format("SELECT structofmaps.map1[\"%s\"] from 
default.structtable LIMIT 1 OFFSET %d", entry.getKey(),
+                        i));
+        Assert.assertEquals(entry.getValue(), queryResult.get(0)[0]);
+      }
+      expectedMap = (Map<?, ?>) expectedStruct.getField("map2");
+      for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
+        List<Object[]> queryResult = shell.executeStatement(String
+                .format("SELECT structofmaps.map2[\"%s\"] from 
default.structtable LIMIT 1 OFFSET %d", entry.getKey(),
+                        i));
+        Assert.assertEquals(entry.getValue(), queryResult.get(0)[0]);
+      }
+    }
+  }
+
+  @Test
+  public void testStructOfStructsInTable() throws IOException {
+    Schema schema = new Schema(
+            required(1, "structofstructs", Types.StructType.of(required(2, 
"struct1", Types.StructType
+                    .of(required(3, "key", Types.StringType.get()), 
required(4, "value",
+                            Types.IntegerType.get()))))));
+    List<Record> records = createTableWithGeneratedRecords(schema, 1, 0L, 
"structtable");
+    // access a struct element inside a struct
+    for (int i = 0; i < records.size(); i++) {
+      GenericRecord expectedStruct = (GenericRecord) 
records.get(i).getField("structofstructs");
+      GenericRecord expectedInnerStruct = (GenericRecord) 
expectedStruct.getField("struct1");
+      List<Object[]> queryResult = shell.executeStatement(String.format(
+              "SELECT structofstructs.struct1.key, 
structofstructs.struct1.value FROM default.structtable " +
+                      "LIMIT 1 OFFSET %d", i));
+      Assert.assertEquals(expectedInnerStruct.getField("key"), 
queryResult.get(0)[0]);
+      Assert.assertEquals(expectedInnerStruct.getField("value"), 
queryResult.get(0)[1]);

Review comment:
       I think these tests may be quite a bit cleaner if this had a method to 
check the result given a schema and the expected record. It would require less 
code in each test case. That's what we do with other tests. Spark, for example, 
has helpers that can check the contents of a generic record against the 
contents of an `InternalRow` or a public `Row`. Probably good as a follow-up to 
this.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to