From 7f28c85370a396e3a00b95d34aec6f60bbcc2f36 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Tue, 21 Aug 2018 12:12:56 +0200 Subject: [PATCH] Merge 'Fix multi-cell static list updates in the presence of ckeys' from Duarte Fixes a regression introduced in 9e88b60ef5f7e1f2ea8078cf6069dcd8f19b1069, which broke the lookup for prefetched values of lists when a clustering key is specified. This is the code that was removed from some list operations: std::experimental::optional row_key; if (!column.is_static()) { row_key = clustering_key::from_clustering_prefix(*params._schema, prefix); } ... auto&& existing_list = params.get_prefetched_list(m.key().view(), row_key, column); Put it back, in the form of common code in the update_parameters class. Fixes #3703 * https://github.com/duarten/scylla cql-list-fixes/v1: tests/cql_query_test: Test multi-cell static list updates with ckeys cql3/lists: Fix multi-cell static list updates in the presence of ckeys keys: Add factory for an empty clustering_key_prefix_view (cherry picked from commit 6937cc2d1c75393944905e7ad31b1f8a862e16e5) --- cql3/update_parameters.cc | 3 ++ keys.hh | 4 +++ tests/cql_query_test.cc | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/cql3/update_parameters.cc b/cql3/update_parameters.cc index 1a0cf16b7a04..564fe6aec1ce 100644 --- a/cql3/update_parameters.cc +++ b/cql3/update_parameters.cc @@ -53,6 +53,9 @@ update_parameters::get_prefetched_list( return {}; } + if (column.is_static()) { + ckey = clustering_key_view::make_empty(); + } auto i = _prefetched->rows.find(std::make_pair(std::move(pkey), std::move(ckey))); if (i == _prefetched->rows.end()) { return {}; diff --git a/keys.hh b/keys.hh index 81f112c7e19e..4e43afcd87ce 100644 --- a/keys.hh +++ b/keys.hh @@ -721,6 +721,10 @@ public: static const compound& get_compound_type(const schema& s) { return s.clustering_key_prefix_type(); } + + static clustering_key_prefix_view make_empty() { + return { bytes_view() }; + } }; class clustering_key_prefix : public prefix_compound_wrapper { diff --git a/tests/cql_query_test.cc b/tests/cql_query_test.cc index 858372578ca0..3990988a33a0 100644 --- a/tests/cql_query_test.cc +++ b/tests/cql_query_test.cc @@ -2622,3 +2622,66 @@ SEASTAR_TEST_CASE(test_empty_partition_range_scan) { assert_that(res).is_rows().is_empty(); }); } + +SEASTAR_TEST_CASE(test_static_multi_cell_static_lists_with_ckey) { + return do_with_cql_env_thread([] (cql_test_env& e) { + e.execute_cql("CREATE TABLE t (p int, c int, slist list static, v int, PRIMARY KEY (p, c));").get(); + e.execute_cql("INSERT INTO t (p, c, slist, v) VALUES (1, 1, [1], 1); ").get(); + + { + e.execute_cql("UPDATE t SET slist[0] = 3, v = 3 WHERE p = 1 AND c = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({{3}}))) }, + { int32_type->decompose(3) } + }); + } + { + e.execute_cql("UPDATE t SET slist = [4], v = 4 WHERE p = 1 AND c = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({{4}}))) }, + { int32_type->decompose(4) } + }); + } + { + e.execute_cql("UPDATE t SET slist = [3] + slist , v = 5 WHERE p = 1 AND c = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({3, 4}))) }, + { int32_type->decompose(5) } + }); + } + { + e.execute_cql("UPDATE t SET slist = slist + [5] , v = 6 WHERE p = 1 AND c = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({3, 4, 5}))) }, + { int32_type->decompose(6) } + }); + } + { + e.execute_cql("DELETE slist[2] from t WHERE p = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({3, 4}))) }, + { int32_type->decompose(6) } + }); + } + { + e.execute_cql("UPDATE t SET slist = slist - [4] , v = 7 WHERE p = 1 AND c = 1;").get(); + auto msg = e.execute_cql("SELECT slist, v FROM t WHERE p = 1 AND c = 1;").get0(); + auto slist_type = list_type_impl::get_instance(int32_type, true); + assert_that(msg).is_rows().with_row({ + { slist_type->decompose(make_list_value(slist_type, list_type_impl::native_type({3}))) }, + { int32_type->decompose(7) } + }); + } + }); +} +