|
16 | 16 |
|
17 | 17 | #include <cstdint> |
18 | 18 | #include <cstring> |
| 19 | +#include <filesystem> |
19 | 20 | #include <limits> |
20 | 21 | #include <map> |
21 | 22 | #include <memory> |
@@ -396,6 +397,76 @@ TEST_P(ScanInteTest, TestScanAppendWithSnapshot3) { |
396 | 397 | CheckResult(expected_data_splits, result_data_splits); |
397 | 398 | } |
398 | 399 |
|
| 400 | +TEST_P(ScanInteTest, TestScanAppendWithSpecificTableSchema) { |
| 401 | + std::string data_dir = paimon::test::GetDataDir(); |
| 402 | + if (!std::filesystem::exists(data_dir + "orc/append_09.db/append_09/schema/schema-0")) { |
| 403 | + data_dir = "../" + data_dir; |
| 404 | + } |
| 405 | + std::string table_path = data_dir + "orc/append_09.db/append_09"; |
| 406 | + |
| 407 | + auto check_result = [&](const std::optional<std::string>& specific_table_schema) { |
| 408 | + ScanContextBuilder context_builder(table_path); |
| 409 | + context_builder.AddOption(Options::SCAN_SNAPSHOT_ID, "3"); |
| 410 | + if (specific_table_schema) { |
| 411 | + context_builder.SetTableSchema(specific_table_schema.value()); |
| 412 | + } |
| 413 | + ASSERT_OK_AND_ASSIGN(auto scan_context, FinishScanContext(context_builder)); |
| 414 | + ASSERT_OK_AND_ASSIGN(auto table_scan, TableScan::Create(std::move(scan_context))); |
| 415 | + ASSERT_OK_AND_ASSIGN(auto result_plan, table_scan->CreatePlan()); |
| 416 | + |
| 417 | + ASSERT_EQ(result_plan->SnapshotId().value(), 3); |
| 418 | + |
| 419 | + auto result_data_splits = CollectDataSplits(result_plan); |
| 420 | + DataSplitImpl::Builder builder1(BinaryRowGenerator::GenerateRow({10}, pool_.get()), |
| 421 | + /*bucket=*/0, /*bucket_path=*/ |
| 422 | + data_dir + "orc/append_09.db/append_09/f1=10/bucket-0", |
| 423 | + {meta_snapshot1_partition10_bucket0_}); |
| 424 | + auto expected_data_split1 = |
| 425 | + std::dynamic_pointer_cast<DataSplitImpl>(builder1.WithTotalBuckets(2) |
| 426 | + .WithSnapshot(3) |
| 427 | + .IsStreaming(false) |
| 428 | + .RawConvertible(true) |
| 429 | + .Build() |
| 430 | + .value()); |
| 431 | + |
| 432 | + DataSplitImpl::Builder builder2( |
| 433 | + BinaryRowGenerator::GenerateRow({10}, pool_.get()), /*bucket=*/1, /*bucket_path=*/ |
| 434 | + data_dir + "orc/append_09.db/append_09/f1=10/bucket-1", |
| 435 | + {meta_snapshot1_partition10_bucket1_, meta_snapshot2_partition10_bucket1_, |
| 436 | + meta_snapshot3_partition10_bucket1_}); |
| 437 | + auto expected_data_split2 = |
| 438 | + std::dynamic_pointer_cast<DataSplitImpl>(builder2.WithTotalBuckets(2) |
| 439 | + .WithSnapshot(3) |
| 440 | + .IsStreaming(false) |
| 441 | + .RawConvertible(true) |
| 442 | + .Build() |
| 443 | + .value()); |
| 444 | + |
| 445 | + DataSplitImpl::Builder builder3( |
| 446 | + BinaryRowGenerator::GenerateRow({20}, pool_.get()), /*bucket=*/0, /*bucket_path=*/ |
| 447 | + data_dir + "orc/append_09.db/append_09/f1=20/bucket-0", |
| 448 | + {meta_snapshot1_partition20_bucket0_, meta_snapshot2_partition20_bucket0_}); |
| 449 | + auto expected_data_split3 = |
| 450 | + std::dynamic_pointer_cast<DataSplitImpl>(builder3.WithTotalBuckets(2) |
| 451 | + .WithSnapshot(3) |
| 452 | + .IsStreaming(false) |
| 453 | + .RawConvertible(true) |
| 454 | + .Build() |
| 455 | + .value()); |
| 456 | + |
| 457 | + std::vector<std::shared_ptr<DataSplitImpl>> expected_data_splits = { |
| 458 | + expected_data_split1, expected_data_split2, expected_data_split3}; |
| 459 | + CheckResult(expected_data_splits, result_data_splits); |
| 460 | + }; |
| 461 | + |
| 462 | + check_result(std::nullopt); |
| 463 | + |
| 464 | + auto fs = std::make_shared<LocalFileSystem>(); |
| 465 | + std::string schema_str; |
| 466 | + ASSERT_OK(fs->ReadFile(table_path + "/schema/schema-0", &schema_str)); |
| 467 | + check_result(std::optional<std::string>(schema_str)); |
| 468 | +} |
| 469 | + |
399 | 470 | TEST_P(ScanInteTest, TestScanInvalidSnapshot) { |
400 | 471 | std::string table_path = paimon::test::GetDataDir() + "orc/append_09.db/append_09"; |
401 | 472 | ScanContextBuilder context_builder(table_path); |
|
0 commit comments