[ASTERIXDB-3440][EXT]: Handle legacy parquet schemas

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- This change handles multiple cases of "repeated"
  converter that is not following the latest parquet
  standards.

Change-Id: I829df08c9ad667562194fbee027f63d8b2b31d4b
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18391
Reviewed-by: Hussain Towaileb <hussainht@gmail.com>
Tested-by: Hussain Towaileb <hussainht@gmail.com>
Integration-Tests: Hussain Towaileb <hussainht@gmail.com>
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/AsterixTypeToParquetTypeVisitor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/AsterixTypeToParquetTypeVisitor.java
index be9690e..254280d 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/AsterixTypeToParquetTypeVisitor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/AsterixTypeToParquetTypeVisitor.java
@@ -26,8 +26,8 @@
 
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.DecimalConverter;
 import org.apache.asterix.external.util.ExternalDataConstants.ParquetOptions;
 import org.apache.asterix.om.types.ARecordType;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/AbstractComplexConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/AbstractComplexConverter.java
new file mode 100644
index 0000000..abf2870
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/AbstractComplexConverter.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.external.input.record.reader.hdfs.parquet.converter;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.AsterixTypeToParquetTypeVisitor;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.ArrayConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.ObjectConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.ObjectRepeatedConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.RepeatedConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.IClosableRepeatedConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.PrimitiveRepeatedConverter;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.data.std.api.IMutableValueStorage;
+import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.parquet.io.api.Converter;
+import org.apache.parquet.io.api.GroupConverter;
+import org.apache.parquet.io.api.PrimitiveConverter;
+import org.apache.parquet.schema.GroupType;
+import org.apache.parquet.schema.LogicalTypeAnnotation;
+import org.apache.parquet.schema.Type;
+import org.apache.parquet.schema.Type.Repetition;
+
+public abstract class AbstractComplexConverter extends GroupConverter
+        implements IFieldValue, IClosableRepeatedConverter {
+    protected AbstractComplexConverter parent;
+    protected IValueReference fieldName;
+    protected String stringFieldName;
+    private int index;
+    protected Converter[] converters;
+    protected ParquetConverterContext context;
+    protected IMutableValueStorage tempStorage;
+
+    protected AbstractComplexConverter(AbstractComplexConverter parent, int index, GroupType parquetType,
+            ParquetConverterContext context) throws IOException {
+        this(parent, null, index, parquetType, context);
+    }
+
+    protected AbstractComplexConverter(AbstractComplexConverter parent, String stringFieldName, int index,
+            GroupType parquetType, ParquetConverterContext context) throws IOException {
+        this.parent = parent;
+        this.stringFieldName = stringFieldName;
+        this.fieldName = context.getSerializedFieldName(stringFieldName);
+        this.index = index;
+        this.context = context;
+        converters = new Converter[parquetType.getFieldCount()];
+        for (int i = 0; i < parquetType.getFieldCount(); i++) {
+            final Type type = parquetType.getType(i);
+
+            LogicalTypeAnnotation typeAnnotation = type.getLogicalTypeAnnotation();
+            if (type.isPrimitive() && type.getRepetition() != Repetition.REPEATED) {
+                converters[i] = createAtomicConverter(parquetType, i);
+            } else if (LogicalTypeAnnotation.listType().equals(typeAnnotation)) {
+                converters[i] = createArrayConverter(parquetType, i);
+            } else if (LogicalTypeAnnotation.mapType().equals(typeAnnotation)
+                    || LogicalTypeAnnotation.MapKeyValueTypeAnnotation.getInstance().equals(typeAnnotation)) {
+                converters[i] = createArrayConverter(parquetType, i);
+            } else if (isRepeated(parquetType, i)) {
+                continue;
+            } else {
+                converters[i] = createObjectConverter(parquetType, i);
+            }
+        }
+    }
+
+    /**
+     * Add child value (the caller is the child itself)
+     *
+     * @param value Child value
+     */
+    public abstract void addValue(IFieldValue value);
+
+    protected abstract PrimitiveConverter createAtomicConverter(GroupType type, int index);
+
+    protected abstract AbstractComplexConverter createArrayConverter(GroupType type, int index);
+
+    protected abstract AbstractComplexConverter createObjectConverter(GroupType type, int index);
+
+    private boolean isRepeated(GroupType parquetType, int index) throws IOException {
+        Type repeatedType = parquetType.getType(index);
+        if (repeatedType.getRepetition() != Repetition.REPEATED) {
+            return false;
+        }
+
+        // primitive type
+        if (repeatedType.isPrimitive()) {
+            if (this.getTypeTag().isListType()) {
+                // legacy 2-levels list, list -> repeated primitive type
+                converters[index] = createAtomicConverter(parquetType, index);
+            } else {
+                // primitive outside ArrayConverter, this is a legacy list of the provided type on its own
+                ATypeTag typeTag = AsterixTypeToParquetTypeVisitor.mapType(repeatedType, context, null);
+                converters[index] =
+                        new PrimitiveRepeatedConverter(typeTag, this, repeatedType.asPrimitiveType(), index, context);
+            }
+        } else {
+            GroupType groupRepeatedType = repeatedType.asGroupType();
+            String name = groupRepeatedType.getName();
+
+            // if contained inside a list, then this is a repeated objects for the list
+            if (this.getTypeTag().isListType()) {
+                if (groupRepeatedType.getFieldCount() > 1 || "array".equals(name) || "key_value".equals(name)) {
+                    // The name "array" and "key_value" are reserved names to represent array of objects
+                    // "key_value" are for MAP type
+                    converters[index] = new ObjectConverter(this, index, groupRepeatedType, context);
+                } else {
+                    // implementation following standards
+                    converters[index] = new RepeatedConverter(this, index, groupRepeatedType, context);
+                }
+            } else {
+                // repeated
+                converters[index] = new ObjectRepeatedConverter(this, name, index, groupRepeatedType, context);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String getStringFieldName() {
+        return stringFieldName;
+    }
+
+    @Override
+    public IValueReference getFieldName() {
+        return fieldName;
+    }
+
+    @Override
+    public int getIndex() {
+        return index;
+    }
+
+    @Override
+    public Converter getConverter(int fieldIndex) {
+        return converters[fieldIndex];
+    }
+
+    public DataOutput getDataOutput() {
+        tempStorage.reset();
+        return tempStorage.getDataOutput();
+    }
+
+    public IMutableValueStorage getValue() {
+        return tempStorage;
+    }
+
+    protected DataOutput getParentDataOutput() {
+        return parent.getDataOutput();
+    }
+
+    protected void addThisValueToParent() {
+        if (parent == null) {
+            //root
+            return;
+        }
+        parent.addValue(this);
+    }
+
+    /**
+     * This closes non-standard repeated converters, check implementers of {@link IClosableRepeatedConverter)
+     */
+    protected void closeDirectRepeatedChildren() {
+        for (Converter converter : converters) {
+            ((IClosableRepeatedConverter) converter).internalEnd();
+        }
+    }
+}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/AbstractComplexConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/AbstractComplexConverter.java
deleted file mode 100644
index 24ec4c9..0000000
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/AbstractComplexConverter.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested;
-
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.hyracks.data.std.api.IMutableValueStorage;
-import org.apache.hyracks.data.std.api.IValueReference;
-import org.apache.parquet.io.api.Converter;
-import org.apache.parquet.io.api.GroupConverter;
-import org.apache.parquet.io.api.PrimitiveConverter;
-import org.apache.parquet.schema.GroupType;
-import org.apache.parquet.schema.LogicalTypeAnnotation;
-import org.apache.parquet.schema.Type;
-import org.apache.parquet.schema.Type.Repetition;
-
-public abstract class AbstractComplexConverter extends GroupConverter implements IFieldValue {
-    protected final AbstractComplexConverter parent;
-    private final IValueReference fieldName;
-    private final String stringFieldName;
-    private final int index;
-    private final Converter[] converters;
-    protected final ParquetConverterContext context;
-    protected IMutableValueStorage tempStorage;
-
-    AbstractComplexConverter(AbstractComplexConverter parent, int index, GroupType parquetType,
-            ParquetConverterContext context) throws IOException {
-        this(parent, null, index, parquetType, context);
-    }
-
-    AbstractComplexConverter(AbstractComplexConverter parent, String stringFieldName, int index, GroupType parquetType,
-            ParquetConverterContext context) throws IOException {
-        this.parent = parent;
-        this.stringFieldName = stringFieldName;
-        this.fieldName = context.getSerializedFieldName(stringFieldName);
-        this.index = index;
-        this.context = context;
-        converters = new Converter[parquetType.getFieldCount()];
-        for (int i = 0; i < parquetType.getFieldCount(); i++) {
-            final Type type = parquetType.getType(i);
-            if (type.isPrimitive()) {
-                converters[i] = createAtomicConverter(parquetType, i);
-            } else if (LogicalTypeAnnotation.listType().equals(type.getLogicalTypeAnnotation())) {
-                converters[i] = createArrayConverter(parquetType, i);
-            } else if (type.getRepetition() == Repetition.REPEATED) {
-                converters[i] = createRepeatedConverter(parquetType, i);
-            } else if (type.getLogicalTypeAnnotation() == LogicalTypeAnnotation.mapType()) {
-                converters[i] = createArrayConverter(parquetType, i);
-            } else {
-                converters[i] = createObjectConverter(parquetType, i);
-            }
-        }
-    }
-
-    /**
-     * Add child value (the caller is the child itself)
-     *
-     * @param value Child value
-     */
-    public abstract void addValue(IFieldValue value);
-
-    protected abstract PrimitiveConverter createAtomicConverter(GroupType type, int index);
-
-    protected abstract AbstractComplexConverter createArrayConverter(GroupType type, int index);
-
-    protected abstract AbstractComplexConverter createObjectConverter(GroupType type, int index);
-
-    /**
-     * Parquet file created by (old) Avro writer treat repeated values differently from files created by Spark.
-     * Example:
-     * Let us consider the object <pre>{"urls":[{"display_url": "string", "expanded_url": "string"}]}</pre>
-     *
-     * @formatter:off
-     *
-     * In Avro:
-     * optional group urls (LIST) {
-     *    repeated group array {
-     *       optional binary display_url (UTF8);
-     *       optional binary expanded_url (UTF8);
-     *    }
-     * }
-     *
-     * In Spark:
-     * optional group urls (LIST) {
-     *    repeated group list {
-     *       // Similar to JSON, the object fields are placed in an inner group
-     *       optional group item {
-     *          optional binary display_url (UTF8);
-     *          optional binary expanded_url (UTF8);
-     *       }
-     *    }
-     * }
-     *
-     * Map type:
-     * required group mapField (MAP) {
-     *    repeated group key_value {
-     *       required int32 key;
-     *       required int32 value;
-     *    }
-     * }
-     *
-     * @formatter:on
-     */
-    protected AbstractComplexConverter createRepeatedConverter(GroupType type, int index) throws IOException {
-        GroupType repeatedType = type.getType(index).asGroupType();
-        String name = repeatedType.getName();
-        if (repeatedType.getFieldCount() > 1 || "array".equals(name) || "key_value".equals(name)) {
-            //The name "array" and "key_value" are reserved names to represent array of objects
-            //"key_value" are for MAP type
-            return new ObjectConverter(this, index, repeatedType, context);
-        }
-        return new RepeatedConverter(this, index, repeatedType, context);
-    }
-
-    @Override
-    public String getStringFieldName() {
-        return stringFieldName;
-    }
-
-    @Override
-    public IValueReference getFieldName() {
-        return fieldName;
-    }
-
-    @Override
-    public int getIndex() {
-        return index;
-    }
-
-    @Override
-    public Converter getConverter(int fieldIndex) {
-        return converters[fieldIndex];
-    }
-
-    public DataOutput getDataOutput() {
-        tempStorage.reset();
-        return tempStorage.getDataOutput();
-    }
-
-    public IMutableValueStorage getValue() {
-        return tempStorage;
-    }
-
-    protected DataOutput getParentDataOutput() {
-        return parent.getDataOutput();
-    }
-
-    protected void addThisValueToParent() {
-        if (parent == null) {
-            //root
-            return;
-        }
-        parent.addValue(this);
-    }
-}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ArrayConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ArrayConverter.java
index 89647e0..0fed70b 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ArrayConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ArrayConverter.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 
 import org.apache.asterix.builders.IAsterixListBuilder;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.PrimitiveConverterProvider;
@@ -31,7 +32,7 @@
 import org.apache.parquet.schema.GroupType;
 import org.apache.parquet.schema.PrimitiveType;
 
-class ArrayConverter extends AbstractComplexConverter {
+public class ArrayConverter extends AbstractComplexConverter {
     private IAsterixListBuilder builder;
 
     public ArrayConverter(AbstractComplexConverter parent, int index, GroupType parquetType,
@@ -52,6 +53,7 @@
 
     @Override
     public void end() {
+        closeDirectRepeatedChildren();
         try {
             builder.write(getParentDataOutput(), true);
         } catch (IOException e) {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectConverter.java
index 542318b..6b63a7b 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectConverter.java
@@ -22,6 +22,7 @@
 
 import org.apache.asterix.builders.IARecordBuilder;
 import org.apache.asterix.external.input.filter.embedder.IExternalFilterValueEmbedder;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.PrimitiveConverterProvider;
@@ -34,7 +35,7 @@
 import org.apache.parquet.schema.GroupType;
 import org.apache.parquet.schema.PrimitiveType;
 
-class ObjectConverter extends AbstractComplexConverter {
+public class ObjectConverter extends AbstractComplexConverter {
     private IARecordBuilder builder;
     /**
      * {@link IExternalFilterValueEmbedder} decides whether the object should be ignored entirely
@@ -66,6 +67,7 @@
 
     @Override
     public void end() {
+        closeDirectRepeatedChildren();
         if (!ignore) {
             writeToParent();
             context.getValueEmbedder().exitObject();
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectRepeatedConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectRepeatedConverter.java
new file mode 100644
index 0000000..ef944ed
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/ObjectRepeatedConverter.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.builders.IARecordBuilder;
+import org.apache.asterix.builders.IAsterixListBuilder;
+import org.apache.asterix.external.input.filter.embedder.IExternalFilterValueEmbedder;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.PrimitiveConverterProvider;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IMutableValueStorage;
+import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.parquet.io.api.PrimitiveConverter;
+import org.apache.parquet.schema.GroupType;
+import org.apache.parquet.schema.PrimitiveType;
+
+/**
+ * Handles the following non-standard parquet schema scenario:
+ * a group repeated list that is not contained in a LIST structure, for example
+ *
+ * {
+ *     "my_group_list": [{"date": "123", "author": "abc"}, {"date": "456", "author": "xyz"}]
+ * }
+ *
+ * Represented as:
+ * message Product {
+ *   repeated group name=my_group_list {
+ *     required binary name=date (STRING);
+ *     required binary name=author (STRING);
+ *   }
+ * }
+ *
+ * Instead of:
+ * message arrow_schema {
+ *   required group myGroupArray (LIST) {
+ *     repeated group list {
+ *       optional group  {
+ *         optional binary hello (STRING);
+ *         optional binary foo (STRING);
+ *       }
+ *     }
+ *   }
+ * }
+ *
+ *  In this case, this is a list and the type of the repeated is the type of the elements in the list
+ */
+public class ObjectRepeatedConverter extends AbstractComplexConverter {
+    private IAsterixListBuilder listBuilder;
+    private IMutableValueStorage listStorage;
+
+    private IARecordBuilder recordBuilder;
+    /**
+     * {@link IExternalFilterValueEmbedder} decides whether the object should be ignored entirely
+     */
+    private boolean ignore = false;
+
+    public ObjectRepeatedConverter(AbstractComplexConverter parent, String stringFieldName, int index,
+            GroupType parquetType, ParquetConverterContext context) throws IOException {
+        super(parent, stringFieldName, index, parquetType, context);
+    }
+
+    @Override
+    public void start() {
+        tempStorage = context.enterObject();
+        recordBuilder = context.getObjectBuilder(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+        IExternalFilterValueEmbedder valueEmbedder = context.getValueEmbedder();
+        if (isRoot()) {
+            valueEmbedder.reset();
+            valueEmbedder.enterObject();
+        } else {
+            ignore = checkValueEmbedder(valueEmbedder);
+        }
+    }
+
+    @Override
+    public void end() {
+        closeDirectRepeatedChildren();
+        if (!ignore) {
+            writeToList();
+            context.getValueEmbedder().exitObject();
+        }
+        context.exitObject(tempStorage, null, recordBuilder);
+        tempStorage = null;
+        recordBuilder = null;
+        ignore = false;
+    }
+
+    private void writeToList() {
+        try {
+            finalizeEmbedding();
+            recordBuilder.write(getListDataOutput(), true);
+            addValueToList();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private void addValueToList() {
+        try {
+            listBuilder.addItem(listStorage);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public DataOutput getListDataOutput() {
+        if (listStorage == null) {
+            internalStart();
+        }
+        listStorage.reset();
+        return listStorage.getDataOutput();
+    }
+
+    @Override
+    public ATypeTag getTypeTag() {
+        return ATypeTag.ARRAY;
+    }
+
+    private void internalStart() {
+        listStorage = context.enterCollection();
+        listBuilder = context.getCollectionBuilder(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+    }
+
+    @Override
+    public void internalEnd() {
+        closeDirectRepeatedChildren();
+        try {
+            listBuilder.write(parent.getDataOutput(), true);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+        parent.addValue(this);
+        context.exitCollection(listStorage, listBuilder);
+        listStorage = null;
+        listBuilder = null;
+    }
+
+    @Override
+    public void addValue(IFieldValue value) {
+        if (ignore) {
+            // The value was embedded already
+            return;
+        }
+        IExternalFilterValueEmbedder valueEmbedder = context.getValueEmbedder();
+        IValueReference fieldName = value.getFieldName();
+        try {
+            if (valueEmbedder.shouldEmbed(value.getStringFieldName(), value.getTypeTag())) {
+                recordBuilder.addField(fieldName, valueEmbedder.getEmbeddedValue());
+            } else {
+                recordBuilder.addField(fieldName, getValue());
+            }
+        } catch (HyracksDataException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    protected PrimitiveConverter createAtomicConverter(GroupType type, int index) {
+        try {
+            PrimitiveType primitiveType = type.getType(index).asPrimitiveType();
+            String childFieldName = type.getFieldName(index);
+            return PrimitiveConverterProvider.createPrimitiveConverter(primitiveType, this, childFieldName, index,
+                    context);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    protected ArrayConverter createArrayConverter(GroupType type, int index) {
+        try {
+            GroupType arrayType = type.getType(index).asGroupType();
+            String childFieldName = type.getFieldName(index);
+            return new ArrayConverter(this, childFieldName, index, arrayType, context);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    protected ObjectConverter createObjectConverter(GroupType type, int index) {
+        try {
+            GroupType objectType = type.getType(index).asGroupType();
+            String childFieldName = type.getFieldName(index);
+            return new ObjectConverter(this, childFieldName, index, objectType, context);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    protected boolean isRoot() {
+        return false;
+    }
+
+    private boolean checkValueEmbedder(IExternalFilterValueEmbedder valueEmbedder) {
+        boolean embed = valueEmbedder.shouldEmbed(getStringFieldName(), ATypeTag.OBJECT);
+        if (embed) {
+            ((ArrayBackedValueStorage) parent.getValue()).set(valueEmbedder.getEmbeddedValue());
+            addValueToList();
+        } else {
+            valueEmbedder.enterObject();
+        }
+        return embed;
+    }
+
+    private void finalizeEmbedding() throws IOException {
+        IExternalFilterValueEmbedder valueEmbedder = context.getValueEmbedder();
+        if (valueEmbedder.isMissingEmbeddedValues()) {
+            String[] embeddedFieldNames = valueEmbedder.getEmbeddedFieldNames();
+            for (int i = 0; i < embeddedFieldNames.length; i++) {
+                String embeddedFieldName = embeddedFieldNames[i];
+                if (valueEmbedder.isMissing(embeddedFieldName)) {
+                    IValueReference embeddedValue = valueEmbedder.getEmbeddedValue();
+                    recordBuilder.addField(context.getSerializedFieldName(embeddedFieldName), embeddedValue);
+                }
+            }
+        }
+    }
+}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/RepeatedConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/RepeatedConverter.java
index 3936ad7..87d0ae4 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/RepeatedConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/nested/RepeatedConverter.java
@@ -21,6 +21,7 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve.PrimitiveConverterProvider;
@@ -29,7 +30,7 @@
 import org.apache.parquet.schema.GroupType;
 import org.apache.parquet.schema.PrimitiveType;
 
-class RepeatedConverter extends AbstractComplexConverter {
+public class RepeatedConverter extends AbstractComplexConverter {
     public RepeatedConverter(AbstractComplexConverter parent, int index, GroupType parquetType,
             ParquetConverterContext context) throws IOException {
         super(parent, index, parquetType, context);
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/BinaryConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/BinaryConverter.java
index 4f371c8..c5e7120 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/BinaryConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/BinaryConverter.java
@@ -20,8 +20,8 @@
 
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.io.api.Binary;
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DateConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DateConverter.java
index 07a5f79..4fd267c 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DateConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DateConverter.java
@@ -20,8 +20,8 @@
 
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 
 class DateConverter extends GenericPrimitiveConverter {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DecimalConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DecimalConverter.java
index 81fb36d..343876c 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DecimalConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/DecimalConverter.java
@@ -23,8 +23,8 @@
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.io.api.Binary;
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/GenericPrimitiveConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/GenericPrimitiveConverter.java
index 20f82f9..e708313 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/GenericPrimitiveConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/GenericPrimitiveConverter.java
@@ -20,16 +20,16 @@
 
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.IFieldValue;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.parquet.io.api.Binary;
 import org.apache.parquet.io.api.PrimitiveConverter;
 
-public class GenericPrimitiveConverter extends PrimitiveConverter implements IFieldValue {
-    private final ATypeTag typeTag;
+public class GenericPrimitiveConverter extends PrimitiveConverter implements IFieldValue, IClosableRepeatedConverter {
+    protected ATypeTag typeTag;
     protected final AbstractComplexConverter parent;
     protected final String stringFieldName;
     protected final IValueReference fieldName;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/IClosableRepeatedConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/IClosableRepeatedConverter.java
new file mode 100644
index 0000000..b23bbf9
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/IClosableRepeatedConverter.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve;
+
+/**
+ * Special case interface to handle scenarios that are not following the latest parquet standards. See implementors
+ * of this interface methods for more details.
+ */
+public interface IClosableRepeatedConverter {
+
+    /**
+     * Calls any necessary end operations for repeated types
+     */
+    default void internalEnd() {
+    }
+}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/JsonStringConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/JsonStringConverter.java
index 8e4c556..7b106e8 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/JsonStringConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/JsonStringConverter.java
@@ -21,8 +21,8 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.external.parser.JSONDataParser;
 import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
 import org.apache.asterix.om.types.ATypeTag;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveConverterProvider.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveConverterProvider.java
index 0f36d11..0e16c21 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveConverterProvider.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveConverterProvider.java
@@ -21,8 +21,8 @@
 import java.io.IOException;
 
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.AsterixTypeToParquetTypeVisitor;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.io.api.PrimitiveConverter;
 import org.apache.parquet.schema.LogicalTypeAnnotation;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveRepeatedConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveRepeatedConverter.java
new file mode 100644
index 0000000..a832484
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/PrimitiveRepeatedConverter.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.primitve;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.builders.IAsterixListBuilder;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IMutableValueStorage;
+import org.apache.parquet.io.api.Binary;
+import org.apache.parquet.schema.PrimitiveType;
+
+/**
+ * Handles the following non-standard parquet schema scenario:
+ * a primitive repeated list that is not contained in a LIST structure, for example
+ *
+ * {
+ *     "my_primitive_array": ["item1", "item2"]
+ * }
+ *
+ * Represented as:
+ * message schema {
+ *  repeated binary name=my_primitive_array (STRING);
+ * }
+ *
+ * Instead of:
+ * message schema {
+ *   required group my_primitive_array (LIST) {
+ *     repeated group list {
+ *       optional binary  (STRING);
+ *     }
+ *   }
+ * }
+ *
+ *  In this case, this is a list and the type of the repeated is the type of the elements in the list
+ */
+public class PrimitiveRepeatedConverter extends GenericPrimitiveConverter {
+    private IAsterixListBuilder builder;
+
+    protected IMutableValueStorage tempStorage;
+
+    public PrimitiveRepeatedConverter(ATypeTag typeTag, AbstractComplexConverter parent, PrimitiveType type, int index,
+            ParquetConverterContext context) throws IOException {
+        super(typeTag, parent, type.getName(), index, context);
+    }
+
+    private void internalStart() {
+        tempStorage = context.enterCollection();
+        builder = context.getCollectionBuilder(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+    }
+
+    @Override
+    public void internalEnd() {
+        try {
+            builder.write(parent.getDataOutput(), true);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+        parent.addValue(this);
+        context.exitCollection(tempStorage, builder);
+        tempStorage = null;
+        builder = null;
+    }
+
+    public DataOutput getDataOutput() {
+        if (tempStorage == null) {
+            internalStart();
+        }
+        tempStorage.reset();
+        return tempStorage.getDataOutput();
+    }
+
+    public void addValue() {
+        try {
+            builder.addItem(tempStorage);
+        } catch (HyracksDataException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public void addBinary(Binary value) {
+        context.serializeString(value, getDataOutput());
+        addValue();
+    }
+
+    @Override
+    public void addBoolean(boolean value) {
+        context.serializeBoolean(value, getDataOutput());
+        addValue();
+    }
+
+    @Override
+    public void addFloat(float value) {
+        addDouble(value);
+    }
+
+    @Override
+    public void addDouble(double value) {
+        context.serializeDouble(value, getDataOutput());
+        addValue();
+    }
+
+    @Override
+    public void addInt(int value) {
+        addLong(value);
+    }
+
+    @Override
+    public void addLong(long value) {
+        context.serializeInt64(value, getDataOutput());
+        addValue();
+    }
+}
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimeConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimeConverter.java
index c78d6e7..e854a64 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimeConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimeConverter.java
@@ -21,8 +21,8 @@
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.schema.LogicalTypeAnnotation;
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimestampConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimestampConverter.java
index c36de37..4d0a61d 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimestampConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/TimestampConverter.java
@@ -22,8 +22,8 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.io.api.Binary;
 import org.apache.parquet.schema.LogicalTypeAnnotation;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UUIDConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UUIDConverter.java
index 23667ca..4384359 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UUIDConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UUIDConverter.java
@@ -20,8 +20,8 @@
 
 import java.io.IOException;
 
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.parquet.io.api.Binary;
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UnsignedIntegerConverter.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UnsignedIntegerConverter.java
index 5bb4ad7..64b0ad7 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UnsignedIntegerConverter.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/hdfs/parquet/converter/primitve/UnsignedIntegerConverter.java
@@ -21,8 +21,8 @@
 import java.io.IOException;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.AbstractComplexConverter;
 import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.ParquetConverterContext;
-import org.apache.asterix.external.input.record.reader.hdfs.parquet.converter.nested.AbstractComplexConverter;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.hyracks.api.exceptions.Warning;