content: /*
   * 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.arrow.adapter.avro;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  
  import java.nio.ByteBuffer;
  import java.nio.charset.StandardCharsets;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  import org.apache.arrow.vector.VectorSchemaRoot;
  import org.apache.arrow.vector.complex.StructVector;
  import org.apache.arrow.vector.types.Types;
  import org.apache.avro.Schema;
  import org.apache.avro.generic.GenericData;
  import org.apache.avro.generic.GenericRecord;
  import org.junit.jupiter.api.Test;
  
  public class AvroSkipFieldTest extends AvroTestBase {
  
    @Test
    public void testSkipUnionWithOneField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_union_before.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_union_one_field_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, i % 2 == 0 ? "test" + i : null);
        record.put(2, i % 2 == 0 ? "test" + i : i);
        record.put(3, i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(1));
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedData.add(expectedRecord);
      }
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipUnionWithNullableOneField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_union_before.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_union_nullable_field_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, i % 2 == 0 ? "test" + i : null);
        record.put(2, i % 2 == 0 ? "test" + i : i);
        record.put(3, i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedData.add(expectedRecord);
      }
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipUnionWithMultiFields() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f2");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_union_before.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_union_multi_fields_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, i % 2 == 0 ? "test" + i : null);
        record.put(2, i % 2 == 0 ? "test" + i : i);
        record.put(3, i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(1));
        expectedRecord.put(2, record.get(3));
        expectedData.add(expectedRecord);
      }
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipMapField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_map_before.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_map_expected.avsc");
  
      HashMap map = new HashMap();
      map.put("key1", "value1");
      map.put("key2", "value3");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, map);
        record.put(2, i % 2 == 0);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(2));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipArrayField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_array_before.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_array_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, Arrays.asList("test" + i, "test" + i));
        record.put(2, i % 2 == 0);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(2));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipMultiFields() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      skipFieldNames.add("f2");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("test_record.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_multi_fields_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, "test" + i);
        record.put(1, i);
        record.put(2, i % 2 == 0);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipStringField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f2");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base1.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_string_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        final byte[] testBytes = ("test" + i).getBytes(StandardCharsets.UTF_8);
        GenericRecord record = new GenericData.Record(schema);
        GenericData.Fixed fixed = new GenericData.Fixed(schema.getField("f0").schema());
        fixed.bytes(testBytes);
        record.put(0, fixed);
        GenericData.EnumSymbol symbol =
            new GenericData.EnumSymbol(schema.getField("f1").schema(), "TEST" + i % 2);
        record.put(1, symbol);
        record.put(2, "testtest" + i);
        record.put(3, ByteBuffer.wrap(testBytes));
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, testBytes);
        expectedRecord.put(1, (byte) i % 2);
        expectedRecord.put(2, testBytes);
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipBytesField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f3");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base1.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_bytes_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        final byte[] testBytes = ("test" + i).getBytes(StandardCharsets.UTF_8);
        GenericRecord record = new GenericData.Record(schema);
        GenericData.Fixed fixed = new GenericData.Fixed(schema.getField("f0").schema());
        fixed.bytes(testBytes);
        record.put(0, fixed);
        GenericData.EnumSymbol symbol =
            new GenericData.EnumSymbol(schema.getField("f1").schema(), "TEST" + i % 2);
        record.put(1, symbol);
        record.put(2, "testtest" + i);
        record.put(3, ByteBuffer.wrap(testBytes));
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, testBytes);
        expectedRecord.put(1, (byte) i % 2);
        expectedRecord.put(2, record.get(2));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipFixedField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base1.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_fixed_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        final byte[] testBytes = ("test" + i).getBytes(StandardCharsets.UTF_8);
        GenericRecord record = new GenericData.Record(schema);
        GenericData.Fixed fixed = new GenericData.Fixed(schema.getField("f0").schema());
        fixed.bytes(testBytes);
        record.put(0, fixed);
        GenericData.EnumSymbol symbol =
            new GenericData.EnumSymbol(schema.getField("f1").schema(), "TEST" + i % 2);
        record.put(1, symbol);
        record.put(2, "testtest" + i);
        record.put(3, ByteBuffer.wrap(testBytes));
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, (byte) i % 2);
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipEnumField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base1.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_fixed_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        final byte[] testBytes = ("test" + i).getBytes(StandardCharsets.UTF_8);
        GenericRecord record = new GenericData.Record(schema);
        GenericData.Fixed fixed = new GenericData.Fixed(schema.getField("f0").schema());
        fixed.bytes(testBytes);
        record.put(0, fixed);
        GenericData.EnumSymbol symbol =
            new GenericData.EnumSymbol(schema.getField("f1").schema(), "TEST" + i % 2);
        record.put(1, symbol);
        record.put(2, "testtest" + i);
        record.put(3, ByteBuffer.wrap(testBytes));
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, testBytes);
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipBooleanField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base2.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_boolean_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, i % 2 == 0);
        record.put(1, i);
        record.put(2, (long) i);
        record.put(3, (float) i);
        record.put(4, (double) i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(1));
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedRecord.put(3, record.get(4));
  
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipIntField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f1");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base2.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_int_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, i % 2 == 0);
        record.put(1, i);
        record.put(2, (long) i);
        record.put(3, (float) i);
        record.put(4, (double) i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(2));
        expectedRecord.put(2, record.get(3));
        expectedRecord.put(3, record.get(4));
  
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipLongField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f2");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base2.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_long_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, i % 2 == 0);
        record.put(1, i);
        record.put(2, (long) i);
        record.put(3, (float) i);
        record.put(4, (double) i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(1));
        expectedRecord.put(2, record.get(3));
        expectedRecord.put(3, record.get(4));
  
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipFloatField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f3");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base2.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_float_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, i % 2 == 0);
        record.put(1, i);
        record.put(2, (long) i);
        record.put(3, (float) i);
        record.put(4, (double) i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(1));
        expectedRecord.put(2, record.get(2));
        expectedRecord.put(3, record.get(4));
  
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipDoubleField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f4");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_base2.avsc");
      Schema expectedSchema = getSchema("skip/test_skip_double_expected.avsc");
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        record.put(0, i % 2 == 0);
        record.put(1, i);
        record.put(2, (long) i);
        record.put(3, (float) i);
        record.put(4, (double) i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, record.get(0));
        expectedRecord.put(1, record.get(1));
        expectedRecord.put(2, record.get(2));
        expectedRecord.put(3, record.get(3));
  
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipRecordField() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("skip/test_skip_record_before.avsc");
      Schema nestedSchema = schema.getFields().get(0).schema();
      ArrayList<GenericRecord> data = new ArrayList<>();
  
      Schema expectedSchema = getSchema("skip/test_skip_record_expected.avsc");
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        GenericRecord nestedRecord = new GenericData.Record(nestedSchema);
        nestedRecord.put(0, "test" + i);
        nestedRecord.put(1, i);
        record.put(0, nestedRecord);
        record.put(1, i);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        expectedRecord.put(0, i);
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipNestedFields() throws Exception {
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0.f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      Schema schema = getSchema("test_nested_record.avsc");
      Schema nestedSchema = schema.getFields().get(0).schema();
      ArrayList<GenericRecord> data = new ArrayList<>();
  
      Schema expectedSchema = getSchema("skip/test_skip_second_level_expected.avsc");
      Schema expectedNestedSchema = expectedSchema.getFields().get(0).schema();
      ArrayList<GenericRecord> expectedData = new ArrayList<>();
  
      for (int i = 0; i < 5; i++) {
        GenericRecord record = new GenericData.Record(schema);
        GenericRecord nestedRecord = new GenericData.Record(nestedSchema);
        nestedRecord.put(0, "test" + i);
        nestedRecord.put(1, i);
        record.put(0, nestedRecord);
        data.add(record);
  
        GenericRecord expectedRecord = new GenericData.Record(expectedSchema);
        GenericRecord expectedNestedRecord = new GenericData.Record(expectedNestedSchema);
        expectedNestedRecord.put(0, nestedRecord.get(1));
        expectedRecord.put(0, expectedNestedRecord);
        expectedData.add(expectedRecord);
      }
  
      VectorSchemaRoot root = writeAndRead(schema, data);
      checkNestedRecordResult(expectedSchema, expectedData, root);
    }
  
    @Test
    public void testSkipThirdLevelField() throws Exception {
      Schema firstLevelSchema = getSchema("skip/test_skip_third_level_expected.avsc");
      Schema secondLevelSchema = firstLevelSchema.getFields().get(0).schema();
      Schema thirdLevelSchema = secondLevelSchema.getFields().get(0).schema();
  
      ArrayList<GenericRecord> data = new ArrayList<>();
      for (int i = 0; i < 5; i++) {
        GenericRecord firstLevelRecord = new GenericData.Record(firstLevelSchema);
        GenericRecord secondLevelRecord = new GenericData.Record(secondLevelSchema);
        GenericRecord thirdLevelRecord = new GenericData.Record(thirdLevelSchema);
  
        thirdLevelRecord.put(0, i);
        thirdLevelRecord.put(1, "test" + i);
        thirdLevelRecord.put(2, i % 2 == 0);
  
        secondLevelRecord.put(0, thirdLevelRecord);
        firstLevelRecord.put(0, secondLevelRecord);
        data.add(firstLevelRecord);
      }
  
      // do not skip any fields first
      VectorSchemaRoot root1 = writeAndRead(firstLevelSchema, data);
  
      assertEquals(1, root1.getFieldVectors().size());
      assertEquals(Types.MinorType.STRUCT, root1.getFieldVectors().get(0).getMinorType());
      StructVector secondLevelVector = (StructVector) root1.getFieldVectors().get(0);
      assertEquals(1, secondLevelVector.getChildrenFromFields().size());
      assertEquals(
          Types.MinorType.STRUCT, secondLevelVector.getChildrenFromFields().get(0).getMinorType());
      StructVector thirdLevelVector = (StructVector) secondLevelVector.getChildrenFromFields().get(0);
      assertEquals(3, thirdLevelVector.getChildrenFromFields().size());
  
      // skip third level field and validate
      Set<String> skipFieldNames = new HashSet<>();
      skipFieldNames.add("f0.f0.f0");
      config =
          new AvroToArrowConfigBuilder(config.getAllocator())
              .setSkipFieldNames(skipFieldNames)
              .build();
      VectorSchemaRoot root2 = writeAndRead(firstLevelSchema, data);
  
      assertEquals(1, root2.getFieldVectors().size());
      assertEquals(Types.MinorType.STRUCT, root2.getFieldVectors().get(0).getMinorType());
      StructVector secondStruct = (StructVector) root2.getFieldVectors().get(0);
      assertEquals(1, secondStruct.getChildrenFromFields().size());
      assertEquals(
          Types.MinorType.STRUCT, secondStruct.getChildrenFromFields().get(0).getMinorType());
      StructVector thirdStruct = (StructVector) secondStruct.getChildrenFromFields().get(0);
      assertEquals(2, thirdStruct.getChildrenFromFields().size());
  
      assertEquals(Types.MinorType.INT, thirdStruct.getChildrenFromFields().get(0).getMinorType());
      assertEquals(Types.MinorType.BIT, thirdStruct.getChildrenFromFields().get(1).getMinorType());
    }
  }
  