|
24 | 24 | import java.util.HashMap; |
25 | 25 | import java.util.List; |
26 | 26 | import java.util.Map; |
| 27 | +import java.util.stream.Collectors; |
| 28 | +import java.util.stream.IntStream; |
27 | 29 | import java.util.stream.Stream; |
28 | 30 |
|
29 | 31 | import org.junit.jupiter.api.Assertions; |
|
32 | 34 | import org.junit.jupiter.params.provider.Arguments; |
33 | 35 | import org.junit.jupiter.params.provider.MethodSource; |
34 | 36 |
|
| 37 | +import com.google.common.base.Strings; |
| 38 | + |
35 | 39 | import org.apache.xtable.exception.PartitionValuesExtractorException; |
36 | 40 | import org.apache.xtable.model.schema.InternalField; |
37 | 41 | import org.apache.xtable.model.schema.InternalPartitionField; |
|
43 | 47 |
|
44 | 48 | public class TestHudiPartitionValuesExtractor { |
45 | 49 |
|
| 50 | + private static final InternalSchema INT_SCHEMA = |
| 51 | + InternalSchema.builder().name("int").dataType(InternalType.INT).build(); |
| 52 | + |
| 53 | + private static final InternalSchema STRING_SCHEMA = |
| 54 | + InternalSchema.builder().name("string").dataType(InternalType.STRING).build(); |
| 55 | + |
46 | 56 | @Test |
47 | 57 | public void testSingleColumn() { |
48 | 58 | InternalPartitionField column = |
@@ -366,7 +376,6 @@ public void testHiveStyle() { |
366 | 376 | .sourceField( |
367 | 377 | InternalField.builder() |
368 | 378 | .name("column2") |
369 | | - .parentPath("base") |
370 | 379 | .schema( |
371 | 380 | InternalSchema.builder().name("long").dataType(InternalType.LONG).build()) |
372 | 381 | .build()) |
@@ -404,7 +413,6 @@ public void testHiveStyleWithDefaultPartition() { |
404 | 413 | .sourceField( |
405 | 414 | InternalField.builder() |
406 | 415 | .name("column2") |
407 | | - .parentPath("base") |
408 | 416 | .schema( |
409 | 417 | InternalSchema.builder().name("long").dataType(InternalType.LONG).build()) |
410 | 418 | .build()) |
@@ -498,4 +506,79 @@ public void testPartitionFormatMismatch() { |
498 | 506 | new HudiPartitionValuesExtractor(pathToPartitionFieldFormat) |
499 | 507 | .extractPartitionValues(Collections.singletonList(column), "2022-10-02")); |
500 | 508 | } |
| 509 | + |
| 510 | + static Stream<Arguments> nestedColumnPartitioning_testArgs() { |
| 511 | + InternalPartitionField p1 = createSimplePartitionField("year", "partition.date", INT_SCHEMA); |
| 512 | + InternalPartitionField p2 = createSimplePartitionField("month", "partition.date", INT_SCHEMA); |
| 513 | + InternalPartitionField p3 = createSimplePartitionField("day", "partition.date", INT_SCHEMA); |
| 514 | + InternalPartitionField p4 = createSimplePartitionField("country", null, STRING_SCHEMA); |
| 515 | + |
| 516 | + return Stream.of( |
| 517 | + // nested column partition, hive style enabled |
| 518 | + Arguments.of( |
| 519 | + Collections.singletonList(p1), |
| 520 | + Collections.singletonList(Range.scalar(2022)), |
| 521 | + "partition.date.year=2022"), |
| 522 | + Arguments.of( |
| 523 | + Arrays.asList(p1, p2), |
| 524 | + Arrays.asList(Range.scalar(2022), Range.scalar(10)), |
| 525 | + "partition.date.year=2022/partition.date.month=10"), |
| 526 | + Arguments.of( |
| 527 | + Arrays.asList(p1, p2, p3), |
| 528 | + Arrays.asList(Range.scalar(2022), Range.scalar(10), Range.scalar(2)), |
| 529 | + "partition.date.year=2022/partition.date.month=10/partition.date.day=2"), |
| 530 | + Arguments.of( |
| 531 | + Arrays.asList(p1, p4), |
| 532 | + Arrays.asList(Range.scalar(2022), Range.scalar("US")), |
| 533 | + "partition.date.year=2022/country=US"), |
| 534 | + |
| 535 | + // nested column partition, hive style disabled |
| 536 | + Arguments.of( |
| 537 | + Collections.singletonList(p1), Collections.singletonList(Range.scalar(2022)), "2022"), |
| 538 | + Arguments.of( |
| 539 | + Arrays.asList(p1, p2), Arrays.asList(Range.scalar(2022), Range.scalar(10)), "2022/10"), |
| 540 | + Arguments.of( |
| 541 | + Arrays.asList(p1, p2, p3), |
| 542 | + Arrays.asList(Range.scalar(2022), Range.scalar(10), Range.scalar(2)), |
| 543 | + "2022/10/2"), |
| 544 | + Arguments.of( |
| 545 | + Arrays.asList(p1, p4), |
| 546 | + Arrays.asList(Range.scalar(2022), Range.scalar("US")), |
| 547 | + "2022/US")); |
| 548 | + } |
| 549 | + |
| 550 | + @ParameterizedTest |
| 551 | + @MethodSource("nestedColumnPartitioning_testArgs") |
| 552 | + void testNestedColumnPartitioning( |
| 553 | + List<InternalPartitionField> partitionFields, |
| 554 | + List<Range> partitionRanges, |
| 555 | + String partitionPath) { |
| 556 | + List<PartitionValue> expected = |
| 557 | + IntStream.range(0, partitionFields.size()) |
| 558 | + .mapToObj( |
| 559 | + i -> |
| 560 | + PartitionValue.builder() |
| 561 | + .partitionField(partitionFields.get(i)) |
| 562 | + .range(partitionRanges.get(i)) |
| 563 | + .build()) |
| 564 | + .collect(Collectors.toList()); |
| 565 | + |
| 566 | + List<PartitionValue> actual = |
| 567 | + new HudiPartitionValuesExtractor(Collections.emptyMap()) |
| 568 | + .extractPartitionValues(partitionFields, partitionPath); |
| 569 | + Assertions.assertEquals(expected, actual); |
| 570 | + } |
| 571 | + |
| 572 | + private static InternalPartitionField createSimplePartitionField( |
| 573 | + String name, String parentPath, InternalSchema schema) { |
| 574 | + InternalField.InternalFieldBuilder sourceFieldBuilder = |
| 575 | + InternalField.builder().name(name).schema(schema); |
| 576 | + if (!Strings.isNullOrEmpty(parentPath)) { |
| 577 | + sourceFieldBuilder.parentPath(parentPath); |
| 578 | + } |
| 579 | + return InternalPartitionField.builder() |
| 580 | + .sourceField(sourceFieldBuilder.build()) |
| 581 | + .transformType(PartitionTransformType.VALUE) |
| 582 | + .build(); |
| 583 | + } |
501 | 584 | } |
0 commit comments