| 519 | using PathAndContent = std::vector<std::pair<std::string, std::string>>; |
| 520 | |
| 521 | void SetUp() override { |
| 522 | // The following test creates 2 sources with divergent but compatible |
| 523 | // schemas. Each source have a common partitioning where the |
| 524 | // fields are not materialized in the data fragments. |
| 525 | // |
| 526 | // Each data is composed of 2 data fragments with divergent but |
| 527 | // compatible schemas. The data fragment within a source share at |
| 528 | // least one column. |
| 529 | // |
| 530 | // Thus, the fixture helps verifying various scenarios where the Scanner |
| 531 | // must fix the RecordBatches to align with the final unified schema exposed |
| 532 | // to the consumer. |
| 533 | static constexpr auto ds1_df1 = "/dataset/alpha/part_ds=1/part_df=1/data.json"; |
| 534 | static constexpr auto ds1_df2 = "/dataset/alpha/part_ds=1/part_df=2/data.json"; |
| 535 | static constexpr auto ds2_df1 = "/dataset/beta/part_ds=2/part_df=1/data.json"; |
| 536 | static constexpr auto ds2_df2 = "/dataset/beta/part_ds=2/part_df=2/data.json"; |
| 537 | auto files = PathAndContent{ |
| 538 | // First Dataset |
| 539 | {ds1_df1, R"([{"phy_1": 111, "phy_2": 211}])"}, |
| 540 | {ds1_df2, R"([{"phy_2": 212, "phy_3": 312}])"}, |
| 541 | // Second Dataset |
| 542 | {ds2_df1, R"([{"phy_3": 321, "phy_4": 421}])"}, |
| 543 | {ds2_df2, R"([{"phy_4": 422, "phy_2": 222}])"}, |
| 544 | }; |
| 545 | |
| 546 | auto mock_fs = std::make_shared<fs::internal::MockFileSystem>(fs::kNoTime); |
| 547 | for (const auto& f : files) { |
| 548 | ARROW_EXPECT_OK(mock_fs->CreateFile(f.first, f.second, /* recursive */ true)); |
| 549 | } |
| 550 | fs_ = mock_fs; |
| 551 | |
| 552 | auto get_source = |
| 553 | [this](std::string base, |
| 554 | std::vector<std::string> paths) -> Result<std::shared_ptr<Dataset>> { |
| 555 | auto resolver = [](const FileSource& source) -> std::shared_ptr<Schema> { |
| 556 | auto path = source.path(); |
| 557 | // A different schema for each data fragment. |
| 558 | if (path == ds1_df1) { |
| 559 | return SchemaFromNames({"phy_1", "phy_2"}); |
| 560 | } else if (path == ds1_df2) { |
| 561 | return SchemaFromNames({"phy_2", "phy_3"}); |
| 562 | } else if (path == ds2_df1) { |
| 563 | return SchemaFromNames({"phy_3", "phy_4"}); |
| 564 | } else if (path == ds2_df2) { |
| 565 | return SchemaFromNames({"phy_4", "phy_2"}); |
| 566 | } |
| 567 | |
| 568 | return nullptr; |
| 569 | }; |
| 570 | |
| 571 | auto format = std::make_shared<JSONRecordBatchFileFormat>(resolver); |
| 572 | |
| 573 | FileSystemFactoryOptions options; |
| 574 | options.partition_base_dir = base; |
| 575 | options.partitioning = |
| 576 | std::make_shared<HivePartitioning>(SchemaFromNames({"part_ds", "part_df"})); |
| 577 | |
| 578 | ARROW_ASSIGN_OR_RAISE(auto factory, |
nothing calls this directly
no test coverage detected