From fcaa743e3da10ea2dedcc7f27641cfb910e23583 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 13 Jun 2016 11:44:47 +0300 Subject: [PATCH] cql3: TINYINT and SMALLINT data type support This adds support for the TINYINT and SMALLINT data types introduced in CQL 3.3.1. Refs #1284 --- cql3/Cql.g | 4 ++++ cql3/constants.cc | 2 ++ cql3/cql3_type.cc | 4 ++++ cql3/cql3_type.hh | 6 +++++- transport/server.cc | 4 ++++ types.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ types.hh | 16 ++++++++++++++++ 7 files changed, 77 insertions(+), 1 deletion(-) diff --git a/cql3/Cql.g b/cql3/Cql.g index beefdf90a0..ba412dfb98 100644 --- a/cql3/Cql.g +++ b/cql3/Cql.g @@ -1465,8 +1465,10 @@ native_type returns [shared_ptr t] | K_FLOAT { $t = cql3_type::float_; } | K_INET { $t = cql3_type::inet; } | K_INT { $t = cql3_type::int_; } + | K_SMALLINT { $t = cql3_type::smallint; } | K_TEXT { $t = cql3_type::text; } | K_TIMESTAMP { $t = cql3_type::timestamp; } + | K_TINYINT { $t = cql3_type::tinyint; } | K_UUID { $t = cql3_type::uuid; } | K_VARCHAR { $t = cql3_type::varchar; } | K_VARINT { $t = cql3_type::varint; } @@ -1644,6 +1646,8 @@ K_DOUBLE: D O U B L E; K_FLOAT: F L O A T; K_INET: I N E T; K_INT: I N T; +K_SMALLINT: S M A L L I N T; +K_TINYINT: T I N Y I N T; K_TEXT: T E X T; K_UUID: U U I D; K_VARCHAR: V A R C H A R; diff --git a/cql3/constants.cc b/cql3/constants.cc index 6aca7c9040..3de44a10ab 100644 --- a/cql3/constants.cc +++ b/cql3/constants.cc @@ -109,7 +109,9 @@ constants::literal::test_assignment(database& db, const sstring& keyspace, ::sha cql3_type::kind::DOUBLE, cql3_type::kind::FLOAT, cql3_type::kind::INT, + cql3_type::kind::SMALLINT, cql3_type::kind::TIMESTAMP, + cql3_type::kind::TINYINT, cql3_type::kind::VARINT>::contains(kind)) { return assignment_testable::test_result::WEAKLY_ASSIGNABLE; } diff --git a/cql3/cql3_type.cc b/cql3/cql3_type.cc index 2521570825..82f018432e 100644 --- a/cql3/cql3_type.cc +++ b/cql3/cql3_type.cc @@ -273,8 +273,10 @@ thread_local shared_ptr cql3_type::boolean = make("boolean", boolean_ thread_local shared_ptr cql3_type::double_ = make("double", double_type, cql3_type::kind::DOUBLE); thread_local shared_ptr cql3_type::float_ = make("float", float_type, cql3_type::kind::FLOAT); thread_local shared_ptr cql3_type::int_ = make("int", int32_type, cql3_type::kind::INT); +thread_local shared_ptr cql3_type::smallint = make("smallint", short_type, cql3_type::kind::SMALLINT); thread_local shared_ptr cql3_type::text = make("text", utf8_type, cql3_type::kind::TEXT); thread_local shared_ptr cql3_type::timestamp = make("timestamp", timestamp_type, cql3_type::kind::TIMESTAMP); +thread_local shared_ptr cql3_type::tinyint = make("tinyint", byte_type, cql3_type::kind::TINYINT); thread_local shared_ptr cql3_type::uuid = make("uuid", uuid_type, cql3_type::kind::UUID); thread_local shared_ptr cql3_type::varchar = make("varchar", utf8_type, cql3_type::kind::TEXT); thread_local shared_ptr cql3_type::timeuuid = make("timeuuid", timeuuid_type, cql3_type::kind::TIMEUUID); @@ -296,8 +298,10 @@ cql3_type::values() { cql3_type::float_, cql3_type:inet, cql3_type::int_, + cql3_type::smallint, cql3_type::text, cql3_type::timestamp, + cql3_type::tinyint, cql3_type::uuid, cql3_type::varchar, cql3_type::varint, diff --git a/cql3/cql3_type.hh b/cql3/cql3_type.hh index 7503b59f95..940ab4b821 100644 --- a/cql3/cql3_type.hh +++ b/cql3/cql3_type.hh @@ -98,7 +98,7 @@ private: public: enum class kind : int8_t { - ASCII, BIGINT, BLOB, BOOLEAN, COUNTER, DECIMAL, DOUBLE, FLOAT, INT, INET, TEXT, TIMESTAMP, UUID, VARCHAR, VARINT, TIMEUUID + ASCII, BIGINT, BLOB, BOOLEAN, COUNTER, DECIMAL, DOUBLE, FLOAT, INT, SMALLINT, TINYINT, INET, TEXT, TIMESTAMP, UUID, VARCHAR, VARINT, TIMEUUID }; using kind_enum = super_enum double_; static thread_local shared_ptr float_; static thread_local shared_ptr int_; + static thread_local shared_ptr smallint; static thread_local shared_ptr text; static thread_local shared_ptr timestamp; + static thread_local shared_ptr tinyint; static thread_local shared_ptr uuid; static thread_local shared_ptr varchar; static thread_local shared_ptr timeuuid; diff --git a/transport/server.cc b/transport/server.cc index 2282ee9998..32de2c73ba 100644 --- a/transport/server.cc +++ b/transport/server.cc @@ -1724,6 +1724,8 @@ private: VARINT = 0x000E, TIMEUUID = 0x000F, INET = 0x0010, + SMALLINT = 0x0013, + TINYINT = 0x0014, LIST = 0x0020, MAP = 0x0021, SET = 0x0022, @@ -1809,6 +1811,8 @@ thread_local const type_codec::type_id_to_type_type type_codec::type_id_to_type (type_id::DOUBLE , double_type) (type_id::FLOAT , float_type) (type_id::INT , int32_type) + (type_id::TINYINT , byte_type) + (type_id::SMALLINT , short_type) (type_id::TIMESTAMP , timestamp_type) (type_id::UUID , uuid_type) (type_id::VARCHAR , utf8_type) diff --git a/types.cc b/types.cc index f4dc820756..73944a7fbb 100644 --- a/types.cc +++ b/types.cc @@ -51,6 +51,8 @@ sstring time_point_to_string(const T& tp) return boost::posix_time::to_iso_extended_string(time); } +static const char* byte_type_name = "org.apache.cassandra.db.marshal.ByteType"; +static const char* short_type_name = "org.apache.cassandra.db.marshal.ShortType"; static const char* int32_type_name = "org.apache.cassandra.db.marshal.Int32Type"; static const char* long_type_name = "org.apache.cassandra.db.marshal.LongType"; static const char* ascii_type_name = "org.apache.cassandra.db.marshal.AsciiType"; @@ -193,6 +195,36 @@ struct integer_type_impl : simple_type_impl { } }; +struct byte_type_impl : integer_type_impl { + byte_type_impl() : integer_type_impl{byte_type_name} + { } + + virtual void validate(bytes_view v) const override { + if (v.size() != 0 && v.size() != 1) { + throw marshal_exception(sprint("Expected 1 byte for a tinyint (%d)", v.size())); + } + } + + virtual ::shared_ptr as_cql3_type() const override { + return cql3::cql3_type::tinyint; + } +}; + +struct short_type_impl : integer_type_impl { + short_type_impl() : integer_type_impl{short_type_name} + { } + + virtual void validate(bytes_view v) const override { + if (v.size() != 0 && v.size() != 2) { + throw marshal_exception(sprint("Expected 2 bytes for a smallint (%d)", v.size())); + } + } + + virtual ::shared_ptr as_cql3_type() const override { + return cql3::cql3_type::smallint; + } +}; + struct int32_type_impl : integer_type_impl { int32_type_impl() : integer_type_impl{int32_type_name} { } @@ -2816,6 +2848,8 @@ reversed_type_impl::native_typeid() const { return _underlying_type->native_typeid(); } +thread_local const shared_ptr byte_type(make_shared()); +thread_local const shared_ptr short_type(make_shared()); thread_local const shared_ptr int32_type(make_shared()); thread_local const shared_ptr long_type(make_shared()); thread_local const shared_ptr ascii_type(make_shared()); @@ -2837,6 +2871,8 @@ thread_local const data_type empty_type(make_shared()); data_type abstract_type::parse_type(const sstring& name) { static thread_local const std::unordered_map types = { + { byte_type_name, byte_type }, + { short_type_name, short_type }, { int32_type_name, int32_type }, { long_type_name, long_type }, { ascii_type_name, ascii_type }, @@ -2894,6 +2930,12 @@ data_value::data_value(const char* v) : data_value(make_new(utf8_type, sstring(v data_value::data_value(bool v) : data_value(make_new(boolean_type, v)) { } +data_value::data_value(int8_t v) : data_value(make_new(byte_type, v)) { +} + +data_value::data_value(int16_t v) : data_value(make_new(short_type, v)) { +} + data_value::data_value(int32_t v) : data_value(make_new(int32_type, v)) { } diff --git a/types.hh b/types.hh index 3a7ffd0432..aa51ff3948 100644 --- a/types.hh +++ b/types.hh @@ -310,6 +310,8 @@ public: data_value(sstring); data_value(const char*); data_value(bool); + data_value(int8_t); + data_value(int16_t); data_value(int32_t); data_value(int64_t); data_value(utils::UUID); @@ -1082,6 +1084,8 @@ abstract_type::as_tri_comparator() const { using key_compare = serialized_compare; // Remember to update type_codec in transport/server.cc and cql3/cql3_type.cc +extern thread_local const shared_ptr byte_type; +extern thread_local const shared_ptr short_type; extern thread_local const shared_ptr int32_type; extern thread_local const shared_ptr long_type; extern thread_local const shared_ptr ascii_type; @@ -1100,6 +1104,18 @@ extern thread_local const shared_ptr decimal_type; extern thread_local const shared_ptr counter_type; extern thread_local const data_type empty_type; +template <> +inline +shared_ptr data_type_for() { + return byte_type; +} + +template <> +inline +shared_ptr data_type_for() { + return short_type; +} + template <> inline shared_ptr data_type_for() {