/*
 * 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.
 */

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "arrow/api.h"
#include "arrow/c/abi.h"
#include "arrow/c/bridge.h"
#include "arrow/ipc/json_simple.h"
#include "gtest/gtest.h"
#include "paimon/commit_context.h"
#include "paimon/common/types/data_field.h"
#include "paimon/common/utils/path_util.h"
#include "paimon/common/utils/string_utils.h"
#include "paimon/core/schema/schema_manager.h"
#include "paimon/core/schema/table_schema.h"
#include "paimon/defs.h"
#include "paimon/file_store_commit.h"
#include "paimon/file_store_write.h"
#include "paimon/fs/file_system_factory.h"
#include "paimon/predicate/literal.h"
#include "paimon/predicate/predicate_builder.h"
#include "paimon/read_context.h"
#include "paimon/reader/batch_reader.h"
#include "paimon/record_batch.h"
#include "paimon/result.h"
#include "paimon/scan_context.h"
#include "paimon/status.h"
#include "paimon/table/source/startup_mode.h"
#include "paimon/table/source/table_read.h"
#include "paimon/table/source/table_scan.h"
#include "paimon/testing/utils/dict_array_converter.h"
#include "paimon/testing/utils/read_result_collector.h"
#include "paimon/testing/utils/test_helper.h"
#include "paimon/testing/utils/testharness.h"
#include "paimon/write_context.h"

namespace paimon {
class DataSplit;
class RecordBatch;
}  // namespace paimon

namespace paimon::test {

class NestedColumnPruningInteTest : public ::testing::Test,
                                    public ::testing::WithParamInterface<std::string> {
    void SetUp() override {
        file_format_ = GetParam();
        dir_ = UniqueTestDirectory::Create("local");
        test_dir_ = dir_->Str();
        table_path_ = PathUtil::JoinPath(test_dir_, "foo.db/bar");
    }
    void TearDown() override {
        dir_.reset();
    }

    void AssertChunkedArrayEquals(const std::shared_ptr<arrow::ChunkedArray>& expected,
                                  const std::shared_ptr<arrow::ChunkedArray>& actual) const {
        arrow::EqualOptions equal_options = arrow::EqualOptions::Defaults();
        bool is_equal = expected->Equals(actual, equal_options.diff_sink(&std::cout));
        if (!is_equal) {
            std::cout << "[expected_type] " << expected->type()->ToString() << std::endl;
            std::cout << "[actual_type]   " << actual->type()->ToString() << std::endl;
            std::cout << "[expected] " << expected->ToString() << std::endl;
            std::cout << "[actual]   " << actual->ToString() << std::endl;
        }
        ASSERT_TRUE(is_equal);
    }

    void ScanReadAndCheck(const std::string& table_path,
                          const std::shared_ptr<arrow::Schema>& expected_schema,
                          const std::string& expected_json,
                          const std::shared_ptr<Predicate>& predicate = nullptr) const {
        ScanContextBuilder scan_context_builder(table_path);
        scan_context_builder.AddOption(Options::SCAN_MODE, StartupMode::LatestFull().ToString());
        if (predicate) {
            scan_context_builder.SetPredicate(predicate);
        }
        ASSERT_OK_AND_ASSIGN(auto scan_context, scan_context_builder.Finish());
        ASSERT_OK_AND_ASSIGN(auto table_scan, TableScan::Create(std::move(scan_context)));
        ASSERT_OK_AND_ASSIGN(auto result_plan, table_scan->CreatePlan());
        ASSERT_FALSE(result_plan->Splits().empty());

        auto c_schema = std::make_unique<ArrowSchema>();
        ASSERT_TRUE(arrow::ExportSchema(*expected_schema, c_schema.get()).ok());
        ReadContextBuilder read_context_builder(table_path);
        read_context_builder.SetReadSchema(std::move(c_schema));
        if (predicate) {
            read_context_builder.SetPredicate(predicate);
        }
        ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
        ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));
        ASSERT_OK_AND_ASSIGN(auto batch_reader, table_read->CreateReader(result_plan->Splits()));
        ASSERT_OK_AND_ASSIGN(auto actual, ReadResultCollector::CollectResult(batch_reader.get()));

        arrow::FieldVector expected_fields = expected_schema->fields();
        expected_fields.insert(expected_fields.begin(), arrow::field("_VALUE_KIND", arrow::int8()));
        auto expected_type = arrow::struct_(expected_fields);
        auto expected = std::make_shared<arrow::ChunkedArray>(
            arrow::ipc::internal::json::ArrayFromJSON(expected_type, expected_json).ValueOrDie());
        AssertChunkedArrayEquals(expected, actual);
    }

 protected:
    std::string file_format_;
    std::string test_dir_;
    std::string table_path_;
    std::unique_ptr<UniqueTestDirectory> dir_;
};

// Test: Table has struct field with 3 sub-fields, read only 1 sub-field via SetReadSchema.
TEST_P(NestedColumnPruningInteTest, PruneStructSubFields) {
    // Table schema: f0 (int32), f1 (struct{a: int32, b: utf8, c: float64})
    auto struct_type = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("b", arrow::utf8()),
        arrow::field("c", arrow::float64()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    // Write data
    std::string data = R"([
        [1, [10, "hello", 1.1]],
        [2, [20, "world", 2.2]],
        [3, [30, "foo", 3.3]],
        [4, [40, "bar", 4.4]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Build projected schema: only read f0 (full) and f1.a (sub-field of struct)
    auto pruned_struct_type = arrow::struct_({
        arrow::field("a", arrow::int32()),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", pruned_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [10]],
        [0, 2, [20]],
        [0, 3, [30]],
        [0, 4, [40]]
    ])");
}

// Test: Projecting a STRUCT column as empty struct should return this column
// as all null values.
TEST_P(NestedColumnPruningInteTest, ProjectStructColumnAsEmptyStructReturnsNullColumn) {
    auto struct_type = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("b", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "x"]],
        [2, [22, "y"]],
        [3, [33, "z"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Project f1 as empty struct.
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", arrow::struct_({})),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, null],
        [0, 2, null],
        [0, 3, null]
    ])");
}

// Test: Two top-level struct columns have the same nested field name; projection should
// distinguish by parent column.
TEST_P(NestedColumnPruningInteTest, PruneSameNestedFieldNameFromDifferentStructColumns) {
    // Table schema: f0 (int32), s0 (struct{f1: int32, a: utf8}), s1 (struct{f1: int32, b: utf8})
    auto s0_type = arrow::struct_({
        arrow::field("f1", arrow::int32()),
        arrow::field("a", arrow::utf8()),
    });
    auto s1_type = arrow::struct_({
        arrow::field("f1", arrow::int32()),
        arrow::field("b", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("s0", s0_type),
        arrow::field("s1", s1_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "left-1"], [101, "right-1"]],
        [2, [22, "left-2"], [202, "right-2"]],
        [3, [33, "left-3"], [303, "right-3"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Project only s0.f1 and s1.f1; both nested field names are identical.
    auto projected_s0 = arrow::struct_({arrow::field("f1", arrow::int32())});
    auto projected_s1 = arrow::struct_({arrow::field("f1", arrow::int32())});
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("s0", projected_s0),
        arrow::field("s1", projected_s1),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [11], [101]],
        [0, 2, [22], [202]],
        [0, 3, [33], [303]]
    ])");
}

// Test: Querying only non-existent struct sub-fields should fail fast.
TEST_P(NestedColumnPruningInteTest, QueryStructSubFieldsAllNonExistent) {
    // Table schema: f0 (int32), f1 (struct{f1: int32, f2: utf8, f3: float64})
    auto struct_type = arrow::struct_({
        arrow::field("f1", arrow::int32()),
        arrow::field("f2", arrow::utf8()),
        arrow::field("f3", arrow::float64()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "a", 1.1]],
        [2, [22, "b", 2.2]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    ASSERT_OK_AND_ASSIGN(auto data_splits,
                         helper->NewScan(StartupMode::LatestFull(), /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    // Query struct sub-fields that do not exist in table schema.
    auto projected_struct_type = arrow::struct_({
        arrow::field("f4", arrow::int32()),
        arrow::field("f5", arrow::int64()),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", projected_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_NOK_WITH_MSG(TableRead::Create(std::move(read_context)),
                        "does not support schema evolution inside struct");
}

// Test: Querying a mix of existent and non-existent struct sub-fields should fail fast.
TEST_P(NestedColumnPruningInteTest, QueryStructSubFieldsWithNonExistentField) {
    // Table schema: f0 (int32), f1 (struct{f1: int32, f2: utf8, f3: float64})
    auto struct_type = arrow::struct_({
        arrow::field("f1", arrow::int32()),
        arrow::field("f2", arrow::utf8()),
        arrow::field("f3", arrow::float64()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "a", 1.1]],
        [2, [22, "b", 2.2]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    ASSERT_OK_AND_ASSIGN(auto data_splits,
                         helper->NewScan(StartupMode::LatestFull(), /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    // Query struct sub-fields f2,f3,f4 where f4 does not exist in table schema.
    auto projected_struct_type = arrow::struct_({
        arrow::field("f2", arrow::utf8()),
        arrow::field("f3", arrow::float64()),
        arrow::field("f4", arrow::int32()),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", projected_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_NOK_WITH_MSG(TableRead::Create(std::move(read_context)),
                        "does not support schema evolution inside struct");
}

// Test: Nested schema divergence (simulated evolution mismatch) must fail fast
// instead of silently skipping nested fields.
TEST_P(NestedColumnPruningInteTest, QueryStructSubFieldsWithTypeMismatchShouldFail) {
    // File schema (old): f1.a is INT32.
    auto struct_type = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("b", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "x"]],
        [2, [22, "y"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Persist schema-2 on disk so table latest schema diverges from old data files.
    std::string file_system_identifier = "local";
    auto fs_iter = options.find(Options::FILE_SYSTEM);
    if (fs_iter != options.end()) {
        file_system_identifier = StringUtils::ToLowerCase(fs_iter->second);
    }
    ASSERT_OK_AND_ASSIGN(auto file_system,
                         FileSystemFactory::Get(file_system_identifier, table_path_, options));
    std::shared_ptr<FileSystem> schema_fs(std::move(file_system));

    SchemaManager schema_manager(schema_fs, table_path_);
    ASSERT_OK_AND_ASSIGN(auto latest_schema_opt, schema_manager.Latest());
    ASSERT_TRUE(latest_schema_opt.has_value());
    auto latest_schema = latest_schema_opt.value();

    auto schema_v2_arrow = arrow::schema({
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", arrow::struct_({
                               arrow::field("a", arrow::utf8()),
                               arrow::field("b", arrow::utf8()),
                           })),
    });
    ASSERT_OK_AND_ASSIGN(
        auto schema_v2,
        TableSchema::Create(/*schema_id=*/latest_schema->Id() + 1, schema_v2_arrow,
                            latest_schema->PartitionKeys(), latest_schema->PrimaryKeys(),
                            latest_schema->Options()));
    ASSERT_OK_AND_ASSIGN(auto schema_v2_json, schema_v2->ToJsonString());
    auto schema_v2_path = PathUtil::JoinPath(schema_manager.SchemaDirectory(),
                                             "schema-" + std::to_string(schema_v2->Id()));
    ASSERT_OK(schema_fs->AtomicStore(schema_v2_path, schema_v2_json));

    ASSERT_OK_AND_ASSIGN(auto data_splits,
                         helper->NewScan(StartupMode::LatestFull(), /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options);
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));

    ASSERT_NOK_WITH_MSG(table_read->CreateReader(data_splits),
                        "PruneDataType nested field type mismatch for 'a': read string vs "
                        "data int32");
}

// Test: With SetReadSchema using the new schema, context build should pass,
// and mismatch against old file type should be rejected in reader creation.
TEST_P(NestedColumnPruningInteTest,
       QueryStructSubFieldsWithTypeMismatchAndSetReadSchemaFailAtContext) {
    // File schema (old): f1.a is INT32.
    auto struct_type = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("b", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [11, "x"]],
        [2, [22, "y"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Persist schema-2 on disk so table latest schema diverges from old data files.
    std::string file_system_identifier = "local";
    auto fs_iter = options.find(Options::FILE_SYSTEM);
    if (fs_iter != options.end()) {
        file_system_identifier = StringUtils::ToLowerCase(fs_iter->second);
    }
    ASSERT_OK_AND_ASSIGN(auto file_system,
                         FileSystemFactory::Get(file_system_identifier, table_path_, options));
    std::shared_ptr<FileSystem> schema_fs(std::move(file_system));

    SchemaManager schema_manager(schema_fs, table_path_);
    ASSERT_OK_AND_ASSIGN(auto latest_schema_opt, schema_manager.Latest());
    ASSERT_TRUE(latest_schema_opt.has_value());
    auto latest_schema = latest_schema_opt.value();

    auto schema_v2_arrow = arrow::schema({
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", arrow::struct_({
                               arrow::field("a", arrow::utf8()),
                               arrow::field("b", arrow::utf8()),
                           })),
    });
    ASSERT_OK_AND_ASSIGN(
        auto schema_v2,
        TableSchema::Create(/*schema_id=*/latest_schema->Id() + 1, schema_v2_arrow,
                            latest_schema->PartitionKeys(), latest_schema->PrimaryKeys(),
                            latest_schema->Options()));
    ASSERT_OK_AND_ASSIGN(auto schema_v2_json, schema_v2->ToJsonString());
    auto schema_v2_path = PathUtil::JoinPath(schema_manager.SchemaDirectory(),
                                             "schema-" + std::to_string(schema_v2->Id()));
    ASSERT_OK(schema_fs->AtomicStore(schema_v2_path, schema_v2_json));

    // User-provided read schema uses latest nested type (a:string).
    auto projected_schema = arrow::schema({
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", arrow::struct_({
                               arrow::field("a", arrow::utf8()),
                               arrow::field("b", arrow::utf8()),
                           })),
    });
    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));
    ASSERT_OK_AND_ASSIGN(auto data_splits,
                         helper->NewScan(StartupMode::LatestFull(), /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    ASSERT_NOK_WITH_MSG(table_read->CreateReader(data_splits),
                        "PruneDataType nested field type mismatch for 'a': read string vs "
                        "data int32");
}

// Test: Read only top-level fields, skip struct entirely.
TEST_P(NestedColumnPruningInteTest, PruneEntireStructField) {
    auto struct_type = arrow::struct_({
        arrow::field("x", arrow::int64()),
        arrow::field("y", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
        arrow::field("f2", arrow::float64()),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [100, [1, "aa"], 0.1],
        [200, [2, "bb"], 0.2],
        [300, [3, "cc"], 0.3]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Only read f0 and f2, skip f1 entirely.
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f2", arrow::float64()),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 100, 0.1],
        [0, 200, 0.2],
        [0, 300, 0.3]
    ])");
}

// Test: Nested struct — prune sub-fields of a struct inside another struct.
TEST_P(NestedColumnPruningInteTest, PruneDeepNestedStruct) {
    // Table schema: f0 (int32), f1 (struct{a: int32, inner: struct{x: int64, y: utf8}})
    auto inner_struct = arrow::struct_({
        arrow::field("x", arrow::int64()),
        arrow::field("y", arrow::utf8()),
    });
    auto outer_struct = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("inner", inner_struct),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", outer_struct),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [10, [100, "aaa"]]],
        [2, [20, [200, "bbb"]]],
        [3, [30, [300, "ccc"]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Projected: f0, f1{inner{x}} — skip f1.a and f1.inner.y
    auto pruned_inner = arrow::struct_({
        arrow::field("x", arrow::int64()),
    });
    auto pruned_outer = arrow::struct_({
        arrow::field("inner", pruned_inner),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", pruned_outer),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [[100]]],
        [0, 2, [[200]]],
        [0, 3, [[300]]]
    ])");
}

// Test: Nested projected schema with special fields under row tracking.
TEST_P(NestedColumnPruningInteTest, PruneNestedStructWithSpecialFields) {
    // Table schema: f0 (int32), f1 (struct{a: int32, inner: struct{x: int64, y: utf8}})
    auto inner_struct = arrow::struct_({
        arrow::field("x", arrow::int64()),
        arrow::field("y", arrow::utf8()),
    });
    auto outer_struct = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("inner", inner_struct),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", outer_struct),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
        {Options::ROW_TRACKING_ENABLED, "true"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [10, [100, "aaa"]]],
        [2, [20, [200, "bbb"]]],
        [3, [30, [300, "ccc"]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    ASSERT_OK_AND_ASSIGN(auto data_splits,
                         helper->NewScan(StartupMode::LatestFull(), /*snapshot_id=*/std::nullopt));

    // Projected: f0, f1{inner{x}}, _SEQUENCE_NUMBER, _ROW_ID
    auto pruned_inner = arrow::struct_({
        arrow::field("x", arrow::int64()),
    });
    auto pruned_outer = arrow::struct_({
        arrow::field("inner", pruned_inner),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", pruned_outer),
        arrow::field("_SEQUENCE_NUMBER", arrow::int64()),
        arrow::field("_ROW_ID", arrow::int64()),
    };
    auto projected_schema = arrow::schema(projected_fields);

    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));
    ASSERT_OK_AND_ASSIGN(auto batch_reader, table_read->CreateReader(data_splits));
    ASSERT_OK_AND_ASSIGN(auto read_result, ReadResultCollector::CollectResult(batch_reader.get()));

    ASSERT_EQ(read_result->num_chunks(), 1);
    auto result_array = std::dynamic_pointer_cast<arrow::StructArray>(read_result->chunk(0));
    ASSERT_TRUE(result_array);

    ASSERT_TRUE(result_array->GetFieldByName("_SEQUENCE_NUMBER"));
    ASSERT_TRUE(result_array->GetFieldByName("_ROW_ID"));
    auto nested_col = result_array->GetFieldByName("f1");
    ASSERT_TRUE(nested_col);

    auto expected_nested_type = arrow::struct_({
        arrow::field("inner", arrow::struct_({arrow::field("x", arrow::int64())})),
    });
    ASSERT_TRUE(nested_col->type()->Equals(expected_nested_type));

    auto expected_nested_array =
        arrow::ipc::internal::json::ArrayFromJSON(expected_nested_type, R"([
            [[100]],
            [[200]],
            [[300]]
        ])")
            .ValueOrDie();
    ASSERT_TRUE(nested_col->Equals(expected_nested_array));
}

// Test: Table has MAP<STRING, INT32> field, read with selected keys filter.
TEST_P(NestedColumnPruningInteTest, MapSelectedKeys) {
    // Table schema: f0 (int32), f1 (map<string, int32>)
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    // Write data: each row has a map with keys "a", "b", "c"
    std::string data = R"([
        [1, [["a", 10], ["b", 20], ["c", 30]]],
        [2, [["a", 100], ["c", 300]]],
        [3, [["b", 200], ["c", 400], ["d", 500]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Build projected schema: read f0 and f1 with selected keys "a,c"
    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"a,c"});
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type)->WithMetadata(selected_keys_metadata),
    };
    auto projected_schema = arrow::schema(projected_fields);

    // Expected: only keys "a" and "c" remain in each map
    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [["a", 10], ["c", 30]]],
        [0, 2, [["a", 100], ["c", 300]]],
        [0, 3, [["c", 400]]]
    ])");
}

// Test: Selected-keys metadata on MAP nested inside STRUCT should be applied.
TEST_P(NestedColumnPruningInteTest, NestedMapSelectedKeysInStruct) {
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    auto struct_type = arrow::struct_({
        arrow::field("m", map_type),
        arrow::field("tag", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [[ ["a", 10], ["b", 20], ["c", 30] ], "r1"]],
        [2, [[ ["a", 100], ["c", 300] ], "r2"]],
        [3, [[ ["b", 200], ["c", 400], ["d", 500] ], "r3"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"a,c"});
    auto projected_struct_type = arrow::struct_({
        arrow::field("m", map_type)->WithMetadata(selected_keys_metadata),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", projected_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [[ ["a", 10], ["c", 30] ]]],
        [0, 2, [[ ["a", 100], ["c", 300] ]]],
        [0, 3, [[ ["c", 400] ]]]
    ])");
}

// Test: Partial STRUCT sub-field recall where one recalled child is MAP with selected keys.
TEST_P(NestedColumnPruningInteTest, PruneStructSubFieldsWithNestedMapSelectedKeys) {
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    auto struct_type = arrow::struct_({
        arrow::field("m", map_type),
        arrow::field("keep", arrow::int64()),
        arrow::field("drop", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [[ ["a", 10], ["b", 20], ["c", 30] ], 1001, "x1"]],
        [2, [[ ["a", 100], ["c", 300] ], 1002, "x2"]],
        [3, [[ ["b", 200], ["c", 400], ["d", 500] ], 1003, "x3"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"a,c"});
    auto projected_struct_type = arrow::struct_({
        arrow::field("m", map_type)->WithMetadata(selected_keys_metadata),
        arrow::field("keep", arrow::int64()),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", projected_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [[ ["a", 10], ["c", 30] ], 1001]],
        [0, 2, [[ ["a", 100], ["c", 300] ], 1002]],
        [0, 3, [[ ["c", 400] ], 1003]]
    ])");
}

// Test: Null semantics should be preserved when pruning STRUCT sub-fields and
// applying selected-keys filtering on nested MAP.
TEST_P(NestedColumnPruningInteTest, PruneStructSubFieldsWithNestedMapSelectedKeysAndNulls) {
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    auto struct_type = arrow::struct_({
        arrow::field("m", map_type),
        arrow::field("keep", arrow::int64()),
        arrow::field("drop", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [[ ["a", 10], ["b", 20], ["c", 30] ], 1001, "x1"]],
        [2, null],
        [3, [null, 1003, "x3"]],
        [4, [[ ["b", 200], ["c", 400], ["d", 500] ], null, "x4"]],
        [5, [[ ["a", 500], ["c", null] ], 1005, "x5"]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"a,c"});
    auto projected_struct_type = arrow::struct_({
        arrow::field("m", map_type)->WithMetadata(selected_keys_metadata),
        arrow::field("keep", arrow::int64()),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", projected_struct_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [[ ["a", 10], ["c", 30] ], 1001]],
        [0, 2, null],
        [0, 3, [null, 1003]],
        [0, 4, [[ ["c", 400] ], null]],
        [0, 5, [[ ["a", 500], ["c", null] ], 1005]]
    ])");
}

// Test: MAP_SELECTED_KEYS metadata value is empty string, select empty-string map key.
TEST_P(NestedColumnPruningInteTest, MapSelectedKeysEmptyStringKey) {
    // Table schema: f0 (int32), f1 (map<string, int32>)
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    // Write data: each row has a map that may contain empty-string key.
    std::string data = R"([
        [1, [["", 9], ["a", 10], ["c", 30]]],
        [2, [["a", 100], ["", 99], ["c", 300]]],
        [3, [["b", 200], ["c", 400], ["d", 500]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Build projected schema: read f0 and f1 with selected keys metadata set to empty string.
    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {""});
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type)->WithMetadata(selected_keys_metadata),
    };
    auto projected_schema = arrow::schema(projected_fields);

    // Expected: only empty-string key remains.
    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [["", 9]]],
        [0, 2, [["", 99]]],
        [0, 3, []]
    ])");
}

// Test: MAP_SELECTED_KEYS output map entry order should follow selected key order.
TEST_P(NestedColumnPruningInteTest, MapSelectedKeysPreserveOrder) {
    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    // Write data with map key order different from selected key order.
    std::string data = R"([
        [1, [["a", 10], ["b", 20], ["c", 30]]],
        [2, [["a", 100], ["c", 300]]],
        [3, [["c", 400], ["a", 500], ["d", 600]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Query key order is c,a and output should follow this order.
    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"c,a"});
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type)->WithMetadata(selected_keys_metadata),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [["c", 30], ["a", 10]]],
        [0, 2, [["c", 300], ["a", 100]]],
        [0, 3, [["c", 400], ["a", 500]]]
    ])");
}

TEST_P(NestedColumnPruningInteTest, NestedStructMapSelectedKeysWithPredicate) {
    if (file_format_ == "avro") {
        return;
    }

    auto map_type = arrow::map(arrow::utf8(), arrow::int32());
    auto info_type = arrow::struct_({
        arrow::field("score", arrow::int64()),
        arrow::field("label", arrow::utf8()),
        arrow::field("drop", arrow::utf8()),
    });
    auto payload_type = arrow::struct_({
        arrow::field("attrs", map_type),
        arrow::field("info", info_type),
        arrow::field("note", arrow::utf8()),
    });
    arrow::FieldVector table_fields = {
        arrow::field("id", arrow::int32()),
        arrow::field("payload", payload_type),
        arrow::field("category", arrow::utf8()),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1048576"},
        {Options::BUCKET, "-1"},
        {Options::WRITE_BATCH_SIZE, "1"},
        {"parquet.page.size", "1"},
        {"parquet.enable-dictionary", "false"},
        {"parquet.write.enable-page-index", "true"},
        {"parquet.write.max-row-group-length", "1"},
        {"parquet.read.enable-page-index-filter", "true"},
        {"orc.stripe.size", "1"},
        {"orc.row.index.stride", "1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));
    WriteContextBuilder write_context_builder(table_path_, "commit_user_1");
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<WriteContext> write_context,
                         write_context_builder.SetOptions(options).Finish());
    ASSERT_OK_AND_ASSIGN(auto file_store_write, FileStoreWrite::Create(std::move(write_context)));

    auto write_one_row = [&](const std::string& data) -> Status {
        PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<RecordBatch> batch,
                               TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                           /*partition_map=*/{}, /*bucket=*/0, {}));
        return file_store_write->Write(std::move(batch));
    };

    ASSERT_OK(write_one_row(
        R"([[1, [[["a", 10], ["b", 20], ["c", 30]], [1001, "low", "x"], "n1"], "hot"]])"));
    ASSERT_OK(write_one_row(
        R"([[12, [[["a", 100], ["c", 300], ["d", 400]], [1002, "mid", "y"], "n2"], "warm"]])"));
    ASSERT_OK(write_one_row(
        R"([[21, [[["b", 200], ["c", 500], ["a", 600]], [1003, "high", "z"], "n3"], "cold"]])"));
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         file_store_write->PrepareCommit(/*wait_compaction=*/false,
                                                         /*commit_identifier=*/0));
    ASSERT_OK(file_store_write->Close());

    CommitContextBuilder commit_context_builder(table_path_, "commit_user_1");
    ASSERT_OK_AND_ASSIGN(std::unique_ptr<CommitContext> commit_context,
                         commit_context_builder.SetOptions(options).Finish());
    ASSERT_OK_AND_ASSIGN(auto commit, FileStoreCommit::Create(std::move(commit_context)));
    ASSERT_OK(commit->Commit(commit_msgs, /*commit_identifier=*/0));

    // Read selected MAP keys together with nested STRUCT sub-fields.
    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"c,a"});
    auto selected_payload_type = arrow::struct_({
        arrow::field("attrs", map_type)->WithMetadata(selected_keys_metadata),
        arrow::field("info", arrow::struct_({arrow::field("score", arrow::int64())})),
    });
    auto selected_schema = arrow::schema({
        arrow::field("id", arrow::int32()),
        arrow::field("payload", selected_payload_type),
    });

    ScanReadAndCheck(table_path_, selected_schema, R"([
        [0, 1, [[["c", 30], ["a", 10]], [1001]]],
        [0, 12, [[["c", 300], ["a", 100]], [1002]]],
        [0, 21, [[["c", 500], ["a", 600]], [1003]]]
    ])");

    // Read only part of top-level columns and part of nested STRUCT fields.
    auto partial_payload_type = arrow::struct_({
        arrow::field("info", arrow::struct_({arrow::field("label", arrow::utf8())})),
    });
    auto partial_schema = arrow::schema({
        arrow::field("payload", partial_payload_type),
        arrow::field("category", arrow::utf8()),
    });

    ScanReadAndCheck(table_path_, partial_schema, R"([
        [0, [["low"]], "hot"],
        [0, [["mid"]], "warm"],
        [0, [["high"]], "cold"]
    ])");

    // Read selected nested fields with predicate pushdown.
    auto predicate = PredicateBuilder::GreaterThan(/*field_index=*/0, /*field_name=*/"id",
                                                   FieldType::INT, Literal(10));

    ScanReadAndCheck(table_path_, selected_schema, R"([
        [0, 12, [[["c", 300], ["a", 100]], [1002]]],
        [0, 21, [[["c", 500], ["a", 600]], [1003]]]
    ])",
                     predicate);
}

// Test: ORC dictionary-encoded map key/value should work with MAP_SELECTED_KEYS.
TEST_P(NestedColumnPruningInteTest, MapSelectedKeysWithOrcDictionaryEncodedMap) {
    if (file_format_ != "orc") {
        GTEST_SKIP() << "ORC-only dictionary encoding case";
    }

    auto map_type = arrow::map(arrow::utf8(), arrow::utf8());
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
        {"orc.read.enable-lazy-decoding", "true"},
        {"orc.dictionary-key-size-threshold", "1.0"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    // Low-cardinality map keys/values increase dictionary-encoding probability for ORC.
    std::string data = R"([
        [1, [["a", "v1"], ["b", "v2"], ["c", "v3"]]],
        [2, [["a", "v1"], ["c", "v3"], ["d", "v4"]]],
        [3, [["a", "v1"], ["b", "v2"], ["e", "v5"]]],
        [4, [["a", "v1"], ["c", "v3"], ["e", "v5"]]],
        [5, [["a", "v1"], ["b", "v2"], ["c", "v3"]]],
        [6, [["a", "v1"], ["c", "v3"], ["d", "v4"]]],
        [7, [["a", "v1"], ["b", "v2"], ["e", "v5"]]],
        [8, [["a", "v1"], ["c", "v3"], ["e", "v5"]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    ASSERT_OK_AND_ASSIGN(auto data_splits, helper->NewScan(StartupMode::LatestFull(),
                                                           /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    auto selected_keys_metadata =
        arrow::KeyValueMetadata::Make({DataField::MAP_SELECTED_KEYS}, {"a,c"});
    auto projected_schema = arrow::schema({
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", map_type)->WithMetadata(selected_keys_metadata),
    });

    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));
    ASSERT_OK_AND_ASSIGN(auto batch_reader, table_read->CreateReader(data_splits));
    ASSERT_OK_AND_ASSIGN(auto read_result, ReadResultCollector::CollectResult(batch_reader.get()));

    ASSERT_OK_AND_ASSIGN(
        auto decoded_result,
        DictArrayConverter::ConvertDictArray(read_result->chunk(0), arrow::default_memory_pool()));
    auto actual_chunked = std::make_shared<arrow::ChunkedArray>(decoded_result);

    auto expected_type = arrow::struct_({
        arrow::field("_VALUE_KIND", arrow::int8()),
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", arrow::map(arrow::utf8(), arrow::utf8())),
    });
    auto expected_array = arrow::ipc::internal::json::ArrayFromJSON(expected_type, R"([
        [0, 1, [["a", "v1"], ["c", "v3"]]],
        [0, 2, [["a", "v1"], ["c", "v3"]]],
        [0, 3, [["a", "v1"]]],
        [0, 4, [["a", "v1"], ["c", "v3"]]],
        [0, 5, [["a", "v1"], ["c", "v3"]]],
        [0, 6, [["a", "v1"], ["c", "v3"]]],
        [0, 7, [["a", "v1"]]],
        [0, 8, [["a", "v1"], ["c", "v3"]]]
    ])")
                              .ValueOrDie();
    auto expected_chunked = std::make_shared<arrow::ChunkedArray>(expected_array);

    AssertChunkedArrayEquals(expected_chunked, actual_chunked);
}

// Test: Deeper nested struct — prune sub-fields of a struct inside a struct inside another
// struct.
TEST_P(NestedColumnPruningInteTest, PruneDeeperNestedStruct) {
    // Table schema: f0 (int32), f1 (struct{a: int32, inner1: struct{x: int64, inner2: struct{p:
    // utf8, q: float64}}})
    auto inner2_struct = arrow::struct_({
        arrow::field("p", arrow::utf8()),
        arrow::field("q", arrow::float64()),
    });
    auto inner1_struct = arrow::struct_({
        arrow::field("x", arrow::int64()),
        arrow::field("inner2", inner2_struct),
    });
    auto outer_struct = arrow::struct_({
        arrow::field("a", arrow::int32()),
        arrow::field("inner1", inner1_struct),
    });
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", outer_struct),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [10, [100, ["ppp", 1.1]]]],
        [2, [20, [200, ["qqq", 2.2]]]],
        [3, [30, [300, ["rrr", 3.3]]]]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    // Projected: f0, f1{inner1{inner2{p}}}
    auto pruned_inner2 = arrow::struct_({
        arrow::field("p", arrow::utf8()),
    });
    auto pruned_inner1 = arrow::struct_({
        arrow::field("inner2", pruned_inner2),
    });
    auto pruned_outer = arrow::struct_({
        arrow::field("inner1", pruned_inner1),
    });
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", pruned_outer),
    };
    auto projected_schema = arrow::schema(projected_fields);

    ScanReadAndCheck(table_path_, projected_schema, R"([
        [0, 1, [[[ "ppp" ]]]],
        [0, 2, [[[ "qqq" ]]]],
        [0, 3, [[[ "rrr" ]]]]
    ])");
}

// Test: Nested pruning for LIST<STRUCT<...>> in integration path.
TEST_P(NestedColumnPruningInteTest, PruneListStructSubFields) {
    auto list_elem_struct = arrow::struct_({
        arrow::field("x", arrow::int64()),
        arrow::field("y", arrow::utf8()),
        arrow::field("z", arrow::float64()),
    });
    auto list_struct_type = arrow::list(arrow::field("item", list_elem_struct));
    arrow::FieldVector table_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", list_struct_type),
    };
    auto table_schema = arrow::schema(table_fields);

    std::map<std::string, std::string> options = {
        {Options::MANIFEST_FORMAT, "AVRO"},
        {Options::FILE_FORMAT, StringUtils::ToUpperCase(file_format_)},
        {Options::TARGET_FILE_SIZE, "1024"},
        {Options::BUCKET, "-1"},
    };

    ASSERT_OK_AND_ASSIGN(
        auto helper, TestHelper::Create(test_dir_, table_schema, /*partition_keys=*/{},
                                        /*primary_keys=*/{}, options, /*is_streaming_mode=*/false));

    std::string data = R"([
        [1, [[100, "a", 1.1], [200, "b", 2.2]]],
        [2, [[300, "c", 3.3]]],
        [3, []]
    ])";
    ASSERT_OK_AND_ASSIGN(auto batch,
                         TestHelper::MakeRecordBatch(arrow::struct_(table_fields), data,
                                                     /*partition_map=*/{}, /*bucket=*/0, {}));
    int64_t commit_identifier = 0;
    ASSERT_OK_AND_ASSIGN(auto commit_msgs,
                         helper->WriteAndCommit(std::move(batch), commit_identifier++,
                                                /*expected_commit_messages=*/std::nullopt));

    ASSERT_OK_AND_ASSIGN(auto data_splits, helper->NewScan(StartupMode::LatestFull(),
                                                           /*snapshot_id=*/std::nullopt));
    ASSERT_FALSE(data_splits.empty());

    auto pruned_list_elem_struct = arrow::struct_({arrow::field("x", arrow::int64())});
    auto pruned_list_type = arrow::list(arrow::field("item", pruned_list_elem_struct));
    arrow::FieldVector projected_fields = {
        arrow::field("f0", arrow::int32()),
        arrow::field("f1", pruned_list_type),
    };
    auto projected_schema = arrow::schema(projected_fields);

    auto c_schema = std::make_unique<ArrowSchema>();
    ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_schema.get()).ok());

    ReadContextBuilder read_context_builder(table_path_);
    read_context_builder.SetOptions(options).SetReadSchema(std::move(c_schema));
    ASSERT_OK_AND_ASSIGN(auto read_context, read_context_builder.Finish());
    ASSERT_OK_AND_ASSIGN(auto table_read, TableRead::Create(std::move(read_context)));
    auto create_reader_result = table_read->CreateReader(data_splits);
    ASSERT_NOK_WITH_MSG(create_reader_result, "partial projection inside list");
}

std::vector<std::string> GetTestValuesForNestedColumnPruningInteTest() {
    std::vector<std::string> values;
    values.emplace_back("parquet");
#ifdef PAIMON_ENABLE_ORC
    values.emplace_back("orc");
#endif
    return values;
}

INSTANTIATE_TEST_SUITE_P(FileFormats, NestedColumnPruningInteTest,
                         ::testing::ValuesIn(GetTestValuesForNestedColumnPruningInteTest()));

}  // namespace paimon::test
