bkietz commented on a change in pull request #9294: URL: https://github.com/apache/arrow/pull/9294#discussion_r566368757
########## File path: cpp/src/arrow/compute/kernels/scalar_cast_test.cc ########## @@ -403,6 +406,77 @@ class TestCast : public TestBase { } }; +TEST_F(TestCast, CanCast) { + auto ExpectCanCast = [](std::shared_ptr<DataType> from, + std::vector<std::shared_ptr<DataType>> to_set, + bool expected = true) { + for (auto to : to_set) { + EXPECT_EQ(CanCast(*from, *to), expected) << " from: " << from->ToString() << "\n" + << " to: " << to->ToString(); + } + }; + + auto ExpectCannotCast = [ExpectCanCast](std::shared_ptr<DataType> from, + std::vector<std::shared_ptr<DataType>> to_set) { + ExpectCanCast(from, to_set, /*expected=*/false); + }; + + ExpectCanCast(null(), {boolean()}); + ExpectCanCast(null(), kNumericTypes); + ExpectCanCast(null(), kBaseBinaryTypes); + ExpectCanCast( + null(), {date32(), date64(), time32(TimeUnit::MILLI), timestamp(TimeUnit::SECOND)}); + ExpectCanCast(dictionary(uint16(), null()), {null()}); + + ExpectCanCast(boolean(), {boolean()}); + ExpectCanCast(boolean(), kNumericTypes); + ExpectCanCast(boolean(), {utf8(), large_utf8()}); + ExpectCanCast(dictionary(int32(), boolean()), {boolean()}); + + ExpectCannotCast(boolean(), {null()}); + ExpectCannotCast(boolean(), {binary(), large_binary()}); + ExpectCannotCast(boolean(), {date32(), date64(), time32(TimeUnit::MILLI), + timestamp(TimeUnit::SECOND)}); + + for (auto from_numeric : kNumericTypes) { + ExpectCanCast(from_numeric, {boolean()}); + ExpectCanCast(from_numeric, kNumericTypes); + ExpectCanCast(from_numeric, {utf8(), large_utf8()}); + ExpectCanCast(dictionary(int32(), from_numeric), {from_numeric}); + + ExpectCannotCast(from_numeric, {null()}); + } + + for (auto from_base_binary : kBaseBinaryTypes) { + ExpectCanCast(from_base_binary, {boolean()}); + ExpectCanCast(from_base_binary, kNumericTypes); + ExpectCanCast(from_base_binary, kBaseBinaryTypes); + ExpectCanCast(dictionary(int64(), from_base_binary), {from_base_binary}); + + // any cast which is valid for the dictionary is valid for the DictionaryArray + ExpectCanCast(dictionary(uint32(), from_base_binary), kBaseBinaryTypes); + ExpectCanCast(dictionary(int16(), from_base_binary), kNumericTypes); + + ExpectCannotCast(from_base_binary, {null()}); + } + + ExpectCanCast(utf8(), {timestamp(TimeUnit::MILLI)}); + ExpectCanCast(large_utf8(), {timestamp(TimeUnit::NANO)}); + ExpectCannotCast(timestamp(TimeUnit::MICRO), + kBaseBinaryTypes); // no formatting supported + + ExpectCannotCast(fixed_size_binary(3), + {fixed_size_binary(3)}); // FIXME missing identity cast + + auto smallint = std::make_shared<SmallintType>(); + ASSERT_OK(RegisterExtensionType(smallint)); + ExpectCanCast(smallint, {int16()}); // cast storage + ExpectCanCast(smallint, + kNumericTypes); // any cast which is valid for storage is supported + ExpectCannotCast(null(), {smallint}); // FIXME missing common cast from null + ASSERT_OK(UnregisterExtensionType("smallint")); Review comment: Will do ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org