ORC-644: Support positional mapping for nested types.
Resolves #522
Signed-off-by: Owen O'Malley <omalley@apache.org>
diff --git a/java/core/src/java/org/apache/orc/Reader.java b/java/core/src/java/org/apache/orc/Reader.java
index 4aa1cff..84c5d91 100644
--- a/java/core/src/java/org/apache/orc/Reader.java
+++ b/java/core/src/java/org/apache/orc/Reader.java
@@ -332,9 +332,9 @@
}
/**
- * Set no. of levels to force schema evolution to be positional instead of
+ * Set number of levels to force schema evolution to be positional instead of
* based on the column names.
- * @param value force positional evolution
+ * @param value number of levels of positional schema evolution
* @return this
*/
public Options positionalEvolutionLevel(int value) {
diff --git a/java/core/src/java/org/apache/orc/impl/SchemaEvolution.java b/java/core/src/java/org/apache/orc/impl/SchemaEvolution.java
index dac5437..d7c6bd2 100644
--- a/java/core/src/java/org/apache/orc/impl/SchemaEvolution.java
+++ b/java/core/src/java/org/apache/orc/impl/SchemaEvolution.java
@@ -497,7 +497,7 @@
if (fileChildren.size() == readerChildren.size()) {
for(int i=0; i < fileChildren.size(); ++i) {
buildConversion(fileChildren.get(i),
- readerChildren.get(i), 0);
+ readerChildren.get(i), positionalLevels - 1);
}
} else {
isOk = false;
diff --git a/java/core/src/test/org/apache/orc/impl/TestSchemaEvolution.java b/java/core/src/test/org/apache/orc/impl/TestSchemaEvolution.java
index f5fe82f..9357c1b 100644
--- a/java/core/src/test/org/apache/orc/impl/TestSchemaEvolution.java
+++ b/java/core/src/test/org/apache/orc/impl/TestSchemaEvolution.java
@@ -1736,6 +1736,49 @@
assertEquals(4, evo.getFileType(4).getId());
}
+ @Test
+ public void testPositionalEvolutionForStructInArray() throws IOException {
+ options.forcePositionalEvolution(true);
+ options.positionalEvolutionLevel(Integer.MAX_VALUE);
+ TypeDescription file = TypeDescription.fromString("array<struct<x:int,y:int,z:int>>");
+ TypeDescription read = TypeDescription.fromString("array<struct<z:int,x:int,a:int,b:int>>");
+ SchemaEvolution evo = new SchemaEvolution(file, read, options);
+ assertEquals(1, evo.getFileType(1).getId());
+ assertEquals(2, evo.getFileType(2).getId());
+ assertEquals(3, evo.getFileType(3).getId());
+ assertEquals(4, evo.getFileType(4).getId());
+ assertEquals(null, evo.getFileType(5));
+ }
+
+ @Test
+ public void testPositionalEvolutionForTwoLayerNestedStruct() throws IOException {
+ options.forcePositionalEvolution(true);
+ options.positionalEvolutionLevel(Integer.MAX_VALUE);
+ TypeDescription file = TypeDescription.fromString("struct<s:struct<x:int,y:int,z:int>>");
+ TypeDescription read = TypeDescription.fromString("struct<s:struct<z:int,x:int,a:int,b:int>>");
+ SchemaEvolution evo = new SchemaEvolution(file, read, options);
+ assertEquals(1, evo.getFileType(1).getId());
+ assertEquals(2, evo.getFileType(2).getId());
+ assertEquals(3, evo.getFileType(3).getId());
+ assertEquals(4, evo.getFileType(4).getId());
+ assertNull(evo.getFileType(5));
+ }
+
+ @Test
+ public void testPositionalEvolutionForThreeLayerNestedStruct() throws IOException {
+ options.forcePositionalEvolution(true);
+ options.positionalEvolutionLevel(Integer.MAX_VALUE);
+ TypeDescription file = TypeDescription.fromString("struct<s1:struct<s2:struct<x:int,y:int,z:int>>>");
+ TypeDescription read = TypeDescription.fromString("struct<s1:struct<s:struct<z:int,x:int,a:int,b:int>>>");
+ SchemaEvolution evo = new SchemaEvolution(file, read, options);
+ assertEquals(1, evo.getFileType(1).getId());
+ assertEquals(2, evo.getFileType(2).getId());
+ assertEquals(3, evo.getFileType(3).getId());
+ assertEquals(4, evo.getFileType(4).getId());
+ assertEquals(5, evo.getFileType(5).getId());
+ assertNull(evo.getFileType(6));
+ }
+
// These are helper methods that pull some of the common code into one
// place.