|
27 | 27 | #include <gtest/gtest.h> |
28 | 28 |
|
29 | 29 | #include "iceberg/expression/literal.h" |
| 30 | +#include "iceberg/schema_field.h" |
30 | 31 | #include "iceberg/test/matchers.h" |
31 | 32 | #include "iceberg/test/temporal_test_helper.h" |
32 | 33 | #include "iceberg/type.h" |
@@ -841,4 +842,76 @@ TEST(TransformSatisfiesOrderOfTest, SatisfiesOrderOf) { |
841 | 842 | } |
842 | 843 | } |
843 | 844 |
|
| 845 | +TEST(TransformCanTransformTest, CanTransform) { |
| 846 | + struct Case { |
| 847 | + std::string transform_str; |
| 848 | + std::shared_ptr<Type> source_type; |
| 849 | + bool expected; |
| 850 | + }; |
| 851 | + |
| 852 | + const std::vector<Case> cases = { |
| 853 | + // Identity can transform all primitive types |
| 854 | + {.transform_str = "identity", .source_type = int32(), .expected = true}, |
| 855 | + {.transform_str = "identity", .source_type = string(), .expected = true}, |
| 856 | + {.transform_str = "identity", .source_type = boolean(), .expected = true}, |
| 857 | + {.transform_str = "identity", |
| 858 | + .source_type = list(SchemaField(123, "element", int32(), false)), |
| 859 | + .expected = false}, |
| 860 | + |
| 861 | + // Void can transform any type |
| 862 | + {.transform_str = "void", .source_type = iceberg::int32(), .expected = true}, |
| 863 | + {.transform_str = "void", |
| 864 | + .source_type = iceberg::map(SchemaField(123, "key", iceberg::string(), false), |
| 865 | + SchemaField(124, "value", iceberg::int32(), true)), |
| 866 | + .expected = true}, |
| 867 | + |
| 868 | + // Bucket can transform specific types |
| 869 | + {.transform_str = "bucket[16]", .source_type = iceberg::int32(), .expected = true}, |
| 870 | + {.transform_str = "bucket[16]", .source_type = iceberg::string(), .expected = true}, |
| 871 | + {.transform_str = "bucket[16]", |
| 872 | + .source_type = iceberg::float32(), |
| 873 | + .expected = false}, |
| 874 | + |
| 875 | + // Truncate can transform specific types |
| 876 | + {.transform_str = "truncate[32]", |
| 877 | + .source_type = iceberg::int32(), |
| 878 | + .expected = true}, |
| 879 | + {.transform_str = "truncate[32]", |
| 880 | + .source_type = iceberg::string(), |
| 881 | + .expected = true}, |
| 882 | + {.transform_str = "truncate[32]", |
| 883 | + .source_type = iceberg::boolean(), |
| 884 | + .expected = false}, |
| 885 | + |
| 886 | + // Year can transform date and timestamp types |
| 887 | + {.transform_str = "year", .source_type = iceberg::date(), .expected = true}, |
| 888 | + {.transform_str = "year", .source_type = iceberg::timestamp(), .expected = true}, |
| 889 | + {.transform_str = "year", .source_type = iceberg::string(), .expected = false}, |
| 890 | + |
| 891 | + // Month can transform date and timestamp types |
| 892 | + {.transform_str = "month", .source_type = iceberg::date(), .expected = true}, |
| 893 | + {.transform_str = "month", .source_type = iceberg::timestamp(), .expected = true}, |
| 894 | + {.transform_str = "month", .source_type = iceberg::binary(), .expected = false}, |
| 895 | + |
| 896 | + // Day can transform date and timestamp types |
| 897 | + {.transform_str = "day", .source_type = iceberg::date(), .expected = true}, |
| 898 | + {.transform_str = "day", .source_type = iceberg::timestamp(), .expected = true}, |
| 899 | + {.transform_str = "day", .source_type = iceberg::uuid(), .expected = false}, |
| 900 | + |
| 901 | + // Hour can transform timestamp types |
| 902 | + {.transform_str = "hour", .source_type = iceberg::timestamp(), .expected = true}, |
| 903 | + {.transform_str = "hour", .source_type = iceberg::timestamp_tz(), .expected = true}, |
| 904 | + {.transform_str = "hour", .source_type = iceberg::int32(), .expected = false}, |
| 905 | + }; |
| 906 | + |
| 907 | + for (const auto& c : cases) { |
| 908 | + auto transform = TransformFromString(c.transform_str); |
| 909 | + ASSERT_TRUE(transform.has_value()) << "Failed to parse: " << c.transform_str; |
| 910 | + |
| 911 | + EXPECT_EQ(transform.value()->CanTransform(*c.source_type), c.expected) |
| 912 | + << "Unexpected result for transform: " << c.transform_str |
| 913 | + << " and source type: " << c.source_type->ToString(); |
| 914 | + } |
| 915 | +} |
| 916 | + |
844 | 917 | } // namespace iceberg |
0 commit comments