From 8836500fcd88add94bbba4cd65575f8c706493ee Mon Sep 17 00:00:00 2001 From: Piotr Sarna Date: Mon, 18 Feb 2019 14:18:32 +0100 Subject: [PATCH] tests: add local indexing test A test case for local indexing is added to the SI suite. --- tests/secondary_index_test.cc | 97 ++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/tests/secondary_index_test.cc b/tests/secondary_index_test.cc index ea1f794810..ca25b11b9b 100644 --- a/tests/secondary_index_test.cc +++ b/tests/secondary_index_test.cc @@ -617,4 +617,99 @@ SEASTAR_TEST_CASE(test_secondary_index_contains_virtual_columns) { assert_that(res).is_rows().with_rows({{{int32_type->decompose(1)}, {int32_type->decompose(1)}, {int32_type->decompose(1)}}}); }); }); -} \ No newline at end of file +} + +SEASTAR_TEST_CASE(test_local_secondary_index) { + return do_with_cql_env_thread([] (cql_test_env& e) { + e.execute_cql("create table t (p int, c int, v1 int, v2 int, primary key(p, c))").get(); + e.execute_cql("create index local_t_v1 on t ((p),v1)").get(); + BOOST_REQUIRE_THROW(e.execute_cql("create index local_t_p on t(p, v2)").get(), std::exception); + BOOST_REQUIRE_THROW(e.execute_cql("create index local_t_p on t((v1), v2)").get(), std::exception); + + e.execute_cql("insert into t (p,c,v1,v2) values (1,1,1,1)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,2,3,2)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,3,3,3)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,4,5,6)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (2,1,3,4)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (2,1,3,5)").get(); + + BOOST_REQUIRE_THROW(e.execute_cql("select * from t where v1 = 1").get(), exceptions::invalid_request_exception); + + auto get_local_index_read_count = [&] { + return e.db().map_reduce0([] (database& local_db) { + return local_db.find_column_family("ks", "local_t_v1_index").get_stats().reads.hist.count; + }, 0, std::plus()).get0(); + }; + + int64_t expected_read_count = 0; + eventually([&] { + auto res = e.execute_cql("select * from t where p = 1 and v1 = 3").get0(); + assert_that(res).is_rows().with_rows({ + {{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(2)}}, + {{int32_type->decompose(1)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}}, + }); + ++expected_read_count; + BOOST_REQUIRE_EQUAL(get_local_index_read_count(), expected_read_count); + }); + + // Even with local indexes present, filtering should work without issues + auto res = e.execute_cql("select * from t where v1 = 1 ALLOW FILTERING").get0(); + assert_that(res).is_rows().with_rows({ + {{int32_type->decompose(1)}, {int32_type->decompose(1)}, {int32_type->decompose(1)}, {int32_type->decompose(1)}}, + }); + BOOST_REQUIRE_EQUAL(get_local_index_read_count(), expected_read_count); + }); +} + +SEASTAR_TEST_CASE(test_local_and_global_secondary_index) { + return do_with_cql_env_thread([] (cql_test_env& e) { + e.execute_cql("create table t (p int, c int, v1 int, v2 int, primary key(p, c))").get(); + e.execute_cql("create index local_t_v1 on t ((p),v1)").get(); + e.execute_cql("create index global_t_v1 on t(v1)").get(); + + e.execute_cql("insert into t (p,c,v1,v2) values (1,1,1,1)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,2,3,2)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,3,3,3)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (1,4,5,6)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (2,1,3,4)").get(); + e.execute_cql("insert into t (p,c,v1,v2) values (2,6,3,5)").get(); + + auto get_local_index_read_count = [&] { + return e.db().map_reduce0([] (database& local_db) { + return local_db.find_column_family("ks", "local_t_v1_index").get_stats().reads.hist.count; + }, 0, std::plus()).get0(); + }; + auto get_global_index_read_count = [&] { + return e.db().map_reduce0([] (database& local_db) { + return local_db.find_column_family("ks", "global_t_v1_index").get_stats().reads.hist.count; + }, 0, std::plus()).get0(); + }; + + int64_t expected_local_index_read_count = 0; + int64_t expected_global_index_read_count = 0; + + eventually([&] { + auto res = e.execute_cql("select * from t where p = 1 and v1 = 3").get0(); + assert_that(res).is_rows().with_rows({ + {{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(2)}}, + {{int32_type->decompose(1)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}}, + }); + ++expected_local_index_read_count; + BOOST_REQUIRE_EQUAL(get_local_index_read_count(), expected_local_index_read_count); + BOOST_REQUIRE_EQUAL(get_global_index_read_count(), expected_global_index_read_count); + }); + + eventually([&] { + auto res = e.execute_cql("select * from t where v1 = 3").get0(); + ++expected_global_index_read_count; + BOOST_REQUIRE_EQUAL(get_local_index_read_count(), expected_local_index_read_count); + BOOST_REQUIRE_EQUAL(get_global_index_read_count(), expected_global_index_read_count); + assert_that(res).is_rows().with_rows_ignore_order({ + {{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(2)}}, + {{int32_type->decompose(1)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}, {int32_type->decompose(3)}}, + {{int32_type->decompose(2)}, {int32_type->decompose(1)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}}, + {{int32_type->decompose(2)}, {int32_type->decompose(6)}, {int32_type->decompose(3)}, {int32_type->decompose(5)}}, + }); + }); + }); +}