diff --git a/configure.py b/configure.py index 88b17da2fa..38adf4af6e 100755 --- a/configure.py +++ b/configure.py @@ -483,7 +483,6 @@ deps = { } tests_not_using_seastar_test_framework = set([ - 'tests/types_test', 'tests/keys_test', 'tests/partitioner_test', 'tests/map_difference_test', diff --git a/tests/types_test.cc b/tests/types_test.cc index 0d41d9a9af..c987905fab 100644 --- a/tests/types_test.cc +++ b/tests/types_test.cc @@ -19,10 +19,7 @@ * along with Scylla. If not, see . */ -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE core - -#include +#include #include #include #include @@ -654,7 +651,7 @@ BOOST_AUTO_TEST_CASE(test_collection_type_compatibility) { } } -BOOST_AUTO_TEST_CASE(test_simple_type_compatibility) { +SEASTAR_TEST_CASE(test_simple_type_compatibility) { test_case tests[] = { { vc, bytes_type, int32_type }, { nc, int32_type, bytes_type }, @@ -668,8 +665,11 @@ BOOST_AUTO_TEST_CASE(test_simple_type_compatibility) { { nc, utf8_type, bytes_type }, { nc, ascii_type, bytes_type }, { nc, ascii_type, utf8_type }, + { cc, timestamp_type, date_type }, + { cc, date_type, timestamp_type }, }; for (auto&& tc : tests) { tc.verify(tc.to, tc.from); } + return make_ready_future<>(); } \ No newline at end of file diff --git a/types.cc b/types.cc index 8856a3e9fb..a30c2e8b9a 100644 --- a/types.cc +++ b/types.cc @@ -48,6 +48,7 @@ static const char* bytes_type_name = "org.apache.cassandra.db.marshal.BytesT static const char* boolean_type_name = "org.apache.cassandra.db.marshal.BooleanType"; static const char* timeuuid_type_name = "org.apache.cassandra.db.marshal.TimeUUIDType"; static const char* timestamp_type_name = "org.apache.cassandra.db.marshal.TimestampType"; +static const char* date_type_name = "org.apache.cassandra.db.marshal.DateType"; static const char* uuid_type_name = "org.apache.cassandra.db.marshal.UUIDType"; static const char* inet_addr_type_name = "org.apache.cassandra.db.marshal.InetAddressType"; static const char* double_type_name = "org.apache.cassandra.db.marshal.DoubleType"; @@ -380,8 +381,10 @@ struct boolean_type_impl : public simple_type_impl { } }; -struct date_type_impl : public concrete_type { - date_type_impl() : concrete_type("date") {} +class date_type_impl : public concrete_type { + static logging::logger _logger; +public: + date_type_impl() : concrete_type(date_type_name) {} virtual void serialize(const void* value, bytes::iterator& out) const override { if (!value) { return; @@ -426,7 +429,21 @@ struct date_type_impl : public concrete_type { virtual bool is_value_compatible_with_internal(const abstract_type& other) const override { return &other == this || &other == timestamp_type.get() || &other == long_type.get(); } + virtual bool is_compatible_with(const abstract_type& other) const override { + if (&other == this) { + return true; + } + if (&other == timestamp_type.get()) { + _logger.warn("Changing from TimestampType to DateType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps " + "(negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. There is no " + "reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to " + "TimestampType by mistake."); + return true; + } + return false; + } }; +logging::logger date_type_impl::_logger(date_type_name); struct timeuuid_type_impl : public concrete_type { timeuuid_type_impl() : concrete_type(timeuuid_type_name) {} @@ -532,7 +549,9 @@ private: friend class uuid_type_impl; }; -struct timestamp_type_impl : simple_type_impl { +class timestamp_type_impl : public simple_type_impl { + static logging::logger _logger; +public: timestamp_type_impl() : simple_type_impl(timestamp_type_name) {} virtual void serialize(const void* value, bytes::iterator& out) const override { if (!value) { @@ -673,7 +692,20 @@ struct timestamp_type_impl : simple_type_impl { virtual bool is_value_compatible_with_internal(const abstract_type& other) const override { return &other == this || &other == date_type.get() || &other == long_type.get(); } + virtual bool is_compatible_with(const abstract_type& other) const override { + if (&other == this) { + return true; + } + if (&other == date_type.get()) { + _logger.warn("Changing from DateType to TimestampType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps " + "(negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. So unless you " + "know that you don't have *any* pre-unix-epoch timestamp you should change back to DateType"); + return true; + } + return false; + } }; +logging::logger timestamp_type_impl::_logger(timestamp_type_name); struct uuid_type_impl : concrete_type { uuid_type_impl() : concrete_type(uuid_type_name) {} @@ -2576,6 +2608,7 @@ data_type abstract_type::parse_type(const sstring& name) { bytes_type_name, bytes_type }, { utf8_type_name, utf8_type }, { boolean_type_name, boolean_type }, + { date_type_name, date_type }, { timeuuid_type_name, timeuuid_type }, { timestamp_type_name, timestamp_type }, { uuid_type_name, uuid_type },