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 },