|
16 | 16 |
|
17 | 17 | #include "paimon/common/data/shredding/map_shared_shredding_utils.h" |
18 | 18 |
|
| 19 | +#include <set> |
| 20 | + |
19 | 21 | #include "arrow/type.h" |
20 | 22 | #include "arrow/util/key_value_metadata.h" |
21 | 23 | #include "gtest/gtest.h" |
@@ -162,6 +164,38 @@ TEST(MapSharedShreddingUtilsTest, LogicalToPhysicalSchemaNoShreddingColumns) { |
162 | 164 | ASSERT_TRUE(physical_schema->Equals(schema)); |
163 | 165 | } |
164 | 166 |
|
| 167 | +TEST(MapSharedShreddingUtilsTest, BuildSpecificPhysicalStructTypeWithOverflow) { |
| 168 | + auto actual = MapSharedShreddingUtils::BuildSpecificPhysicalStructType( |
| 169 | + arrow::int64(), /*physical_col_ids=*/{3, 1}, /*value_nullable=*/false, |
| 170 | + /*include_overflow=*/true); |
| 171 | + |
| 172 | + auto expected = arrow::struct_({ |
| 173 | + arrow::field("__field_mapping", arrow::list(arrow::int32()), true), |
| 174 | + arrow::field("__col_1", arrow::int64(), false), |
| 175 | + arrow::field("__col_3", arrow::int64(), false), |
| 176 | + arrow::field("__overflow", |
| 177 | + arrow::map(arrow::int32(), arrow::field("value", arrow::int64(), false)), |
| 178 | + true), |
| 179 | + }); |
| 180 | + ASSERT_TRUE(actual->Equals(*expected)) << "Expected:\n" |
| 181 | + << expected->ToString() << "\nActual:\n" |
| 182 | + << actual->ToString(); |
| 183 | +} |
| 184 | + |
| 185 | +TEST(MapSharedShreddingUtilsTest, BuildSpecificPhysicalStructTypeWithoutOverflow) { |
| 186 | + auto actual = MapSharedShreddingUtils::BuildSpecificPhysicalStructType( |
| 187 | + arrow::utf8(), /*physical_col_ids=*/{3}, /*value_nullable=*/true, |
| 188 | + /*include_overflow=*/false); |
| 189 | + |
| 190 | + auto expected = arrow::struct_({ |
| 191 | + arrow::field("__field_mapping", arrow::list(arrow::int32()), true), |
| 192 | + arrow::field("__col_3", arrow::utf8(), true), |
| 193 | + }); |
| 194 | + ASSERT_TRUE(actual->Equals(*expected)) << "Expected:\n" |
| 195 | + << expected->ToString() << "\nActual:\n" |
| 196 | + << actual->ToString(); |
| 197 | +} |
| 198 | + |
165 | 199 | // ---- BuildColumnToNumColumns ---- |
166 | 200 |
|
167 | 201 | TEST(MapSharedShreddingUtilsTest, BuildColumnToNumColumns) { |
@@ -362,4 +396,94 @@ TEST(MapSharedShreddingUtilsTest, PhysicalColumnName) { |
362 | 396 | ASSERT_EQ(MapSharedShreddingDefine::PhysicalColumnName(99), "__col_99"); |
363 | 397 | } |
364 | 398 |
|
| 399 | +// ---- GetPhysicalColumnIndices ---- |
| 400 | + |
| 401 | +// Normal: single physical column per field |
| 402 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesSingleColumn) { |
| 403 | + MapSharedShreddingFieldMeta meta; |
| 404 | + meta.name_to_id = {{"age", 0}, {"name", 1}}; |
| 405 | + meta.field_to_columns = {{0, {2}}, {1, {5}}}; |
| 406 | + |
| 407 | + ASSERT_OK_AND_ASSIGN(auto cols_age, |
| 408 | + MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "age")); |
| 409 | + ASSERT_EQ(cols_age, (std::vector<int32_t>{2})); |
| 410 | + |
| 411 | + ASSERT_OK_AND_ASSIGN(auto cols_name, |
| 412 | + MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "name")); |
| 413 | + ASSERT_EQ(cols_name, (std::vector<int32_t>{5})); |
| 414 | +} |
| 415 | + |
| 416 | +// Normal: multiple physical columns for one field |
| 417 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesMultipleColumns) { |
| 418 | + MapSharedShreddingFieldMeta meta; |
| 419 | + meta.name_to_id = {{"tags", 0}}; |
| 420 | + meta.field_to_columns = {{0, {0, 3, 7}}}; |
| 421 | + |
| 422 | + ASSERT_OK_AND_ASSIGN(auto cols, |
| 423 | + MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "tags")); |
| 424 | + ASSERT_EQ(cols, (std::vector<int32_t>{0, 3, 7})); |
| 425 | +} |
| 426 | + |
| 427 | +// Normal: many fields each mapping to different physical columns |
| 428 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesMultipleFields) { |
| 429 | + MapSharedShreddingFieldMeta meta; |
| 430 | + meta.name_to_id = {{"a", 0}, {"b", 1}, {"c", 2}}; |
| 431 | + meta.field_to_columns = {{0, {0, 1}}, {1, {2, 3, 4}}, {2, {5}}}; |
| 432 | + |
| 433 | + ASSERT_OK_AND_ASSIGN(auto cols_a, MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "a")); |
| 434 | + ASSERT_EQ(cols_a, (std::vector<int32_t>{0, 1})); |
| 435 | + |
| 436 | + ASSERT_OK_AND_ASSIGN(auto cols_b, MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "b")); |
| 437 | + ASSERT_EQ(cols_b, (std::vector<int32_t>{2, 3, 4})); |
| 438 | + |
| 439 | + ASSERT_OK_AND_ASSIGN(auto cols_c, MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "c")); |
| 440 | + ASSERT_EQ(cols_c, (std::vector<int32_t>{5})); |
| 441 | +} |
| 442 | + |
| 443 | +// Error: field name not found in name_to_id |
| 444 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesFieldNotFound) { |
| 445 | + MapSharedShreddingFieldMeta meta; |
| 446 | + meta.name_to_id = {{"age", 0}}; |
| 447 | + meta.field_to_columns = {{0, {1}}}; |
| 448 | + |
| 449 | + ASSERT_NOK_WITH_MSG(MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "nonexistent"), |
| 450 | + "cannot find field nonexistent in map shared shredding meta"); |
| 451 | +} |
| 452 | + |
| 453 | +// Error: field name not found in empty meta |
| 454 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesEmptyMeta) { |
| 455 | + MapSharedShreddingFieldMeta meta; |
| 456 | + ASSERT_NOK_WITH_MSG(MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "any"), |
| 457 | + "cannot find field any in map shared shredding meta"); |
| 458 | +} |
| 459 | + |
| 460 | +// Error: field id exists in name_to_id but is missing from field_to_columns |
| 461 | +TEST(MapSharedShreddingUtilsTest, GetPhysicalColumnIndicesFieldIdMissingInFieldToColumns) { |
| 462 | + MapSharedShreddingFieldMeta meta; |
| 463 | + // "score" -> field_id 42, but field_to_columns has no entry for 42 |
| 464 | + meta.name_to_id = {{"score", 42}}; |
| 465 | + meta.field_to_columns = {}; |
| 466 | + |
| 467 | + ASSERT_NOK_WITH_MSG(MapSharedShreddingUtils::GetPhysicalColumnIndices(meta, "score"), |
| 468 | + "cannot find field id 42 in field_to_columns in map shared shredding meta"); |
| 469 | +} |
| 470 | + |
| 471 | +TEST(MapSharedShreddingUtilsTest, IsOverflowField) { |
| 472 | + MapSharedShreddingFieldMeta meta; |
| 473 | + meta.name_to_id = {{"a", 0}, {"b", 1}, {"c", 2}}; |
| 474 | + meta.overflow_field_set = {0, 2}; |
| 475 | + |
| 476 | + ASSERT_OK_AND_ASSIGN(bool a_overflow, MapSharedShreddingUtils::IsOverflowField(meta, "a")); |
| 477 | + ASSERT_TRUE(a_overflow); |
| 478 | + |
| 479 | + ASSERT_OK_AND_ASSIGN(bool b_overflow, MapSharedShreddingUtils::IsOverflowField(meta, "b")); |
| 480 | + ASSERT_FALSE(b_overflow); |
| 481 | + |
| 482 | + ASSERT_OK_AND_ASSIGN(bool c_overflow, MapSharedShreddingUtils::IsOverflowField(meta, "c")); |
| 483 | + ASSERT_TRUE(c_overflow); |
| 484 | + |
| 485 | + ASSERT_NOK_WITH_MSG(MapSharedShreddingUtils::IsOverflowField(meta, "missing"), |
| 486 | + "cannot find field missing in map shared shredding meta"); |
| 487 | +} |
| 488 | + |
365 | 489 | } // namespace paimon::test |
0 commit comments