From 9c33e1afcf499f812258d2f1a53bf8114ff4bbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 17 Aug 2015 14:22:46 +0200 Subject: [PATCH 1/5] types: add is_tuple() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Dziepak --- types.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types.hh b/types.hh index 1a9f583b01..1c85001c92 100644 --- a/types.hh +++ b/types.hh @@ -303,6 +303,7 @@ public: virtual bool is_collection() const { return false; } virtual bool is_multi_cell() const { return false; } virtual bool is_reversed() const { return false; } + virtual bool is_tuple() const { return false; } virtual ::shared_ptr as_cql3_type() const = 0; virtual shared_ptr freeze() const { return shared_from_this(); } friend class list_type_impl; @@ -1061,6 +1062,7 @@ public: virtual bool is_compatible_with(const abstract_type& previous) const override; virtual bool is_value_compatible_with_internal(const abstract_type& previous) const override; virtual shared_ptr as_cql3_type() const override; + virtual bool is_tuple() const override { return true; } private: bool check_compatibility(const abstract_type& previous, bool (abstract_type::*predicate)(const abstract_type&) const) const; static sstring make_name(const std::vector& types); From 08b2c5801d16aabc555bf4e693b904ea944d5413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 17 Aug 2015 14:24:17 +0200 Subject: [PATCH 2/5] types: tuple: use fully qualified class name as type name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Dziepak --- types.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types.cc b/types.cc index 279e365c09..948f46e9ee 100644 --- a/types.cc +++ b/types.cc @@ -2053,7 +2053,7 @@ tuple_type_impl::as_cql3_type() const { sstring tuple_type_impl::make_name(const std::vector& types) { - return sprint("tuple<%s>", ::join(", ", types | boost::adaptors::transformed(std::mem_fn(&abstract_type::name)))); + return sprint("org.apache.cassandra.db.marshal.TupleType(%s)", ::join(", ", types | boost::adaptors::transformed(std::mem_fn(&abstract_type::name)))); } sstring From f846eb2032153392532bcd91292581031c292bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 17 Aug 2015 14:25:39 +0200 Subject: [PATCH 3/5] types: tuple: fix std::move() in constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In an expression like: tuple_type_impl(make_name(types), std::move(types)); the order in which arguments are evaluated is unspecified and it is possible that make_name() is called with types already moved away. This is fixed by using initialization list (for which order of evalutaion is specified). Unfortunately, this also requires some code duplication. Signed-off-by: Paweł Dziepak --- types.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types.cc b/types.cc index 948f46e9ee..070fb6ee74 100644 --- a/types.cc +++ b/types.cc @@ -1913,7 +1913,10 @@ tuple_type_impl::tuple_type_impl(sstring name, std::vector types) } tuple_type_impl::tuple_type_impl(std::vector types) - : tuple_type_impl(make_name(types), std::move(types)) { + : abstract_type(make_name(types)), _types(std::move(types)) { + for (auto& t : _types) { + t = t->freeze(); + } } shared_ptr From 944d0e53669b3e5e4c3eae5d3884fa0673b56acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 17 Aug 2015 14:42:21 +0200 Subject: [PATCH 4/5] transport: encode tuple types properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Dziepak --- transport/server.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/transport/server.cc b/transport/server.cc index 438df763fa..ce034fe244 100644 --- a/transport/server.cc +++ b/transport/server.cc @@ -1201,6 +1201,15 @@ public: if (type->is_reversed()) { fail(unimplemented::cause::REVERSED); } + if (type->is_tuple()) { + r.write_short(uint16_t(type_id::TUPLE)); + auto ttype = static_pointer_cast(type); + r.write_short(ttype->size()); + for (auto&& t : ttype->all_types()) { + encode(r, t); + } + return; + } if (type->is_collection()) { auto&& ctype = static_cast(type.get()); if (&ctype->_kind == &collection_type_impl::kind::map) { From 4e3f81ee62aee6bcceadb24b5c13d7676fb96a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Mon, 17 Aug 2015 14:43:43 +0200 Subject: [PATCH 5/5] tests/cql3: test_tuples: test table creation as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Dziepak --- tests/cql_query_test.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cql_query_test.cc b/tests/cql_query_test.cc index 5c2abea770..6b8cc54ba1 100644 --- a/tests/cql_query_test.cc +++ b/tests/cql_query_test.cc @@ -1012,6 +1012,15 @@ SEASTAR_TEST_CASE(test_tuples) { .with_rows({{ {tt->decompose(tuple_type_impl::native_type({int32_t(1001), int64_t(2001), sstring("abc1")}))}, }}); + return e.execute_cql("create table cf2 (p1 int PRIMARY KEY, r1 tuple)").discard_result(); + }).then([&e] { + return e.execute_cql("insert into cf2 (p1, r1) values (1, (1, 2, 'abc'));").discard_result(); + }).then([&e] { + return e.execute_cql("select * from cf2 where p1 = 1;"); + }).then([&e, tt] (auto msg) { + assert_that(msg).is_rows().with_rows({ + { int32_type->decompose(int32_t(1)), tt->decompose(tuple_type_impl::native_type({int32_t(1), int64_t(2), sstring("abc")})) } + }); }); }); }