index, tests: add token column to secondary index schema

Additional token column is now present in every view schema
that backs a secondary index. This column is always a first part
of the clustering key, so it forces token order on queries.
Column's name is ideally idx_token, but can be postfixed
with a number to ensure its uniqueness.

It also updates tests to make them acknowledge the new token order.

Fixes #3423
This commit is contained in:
Piotr Sarna
2018-06-04 17:10:53 +02:00
parent d5e7b5507b
commit 4a9bf7ed5b
2 changed files with 21 additions and 10 deletions

View File

@@ -98,6 +98,16 @@ static sstring index_table_name(const sstring& index_name) {
return sprint("%s_index", index_name);
}
static bytes get_available_token_column_name(const schema& schema) {
bytes base_name = "idx_token";
bytes accepted_name = base_name;
int i = 0;
while (schema.get_column_definition(accepted_name)) {
accepted_name = base_name + to_bytes("_")+ to_bytes(std::to_string(++i));
}
return accepted_name;
}
view_ptr secondary_index_manager::create_view_for_index(const index_metadata& im) const {
auto schema = _cf.schema();
sstring index_target_name = im.options().at(cql3::statements::index_target::target_option_name);
@@ -109,6 +119,9 @@ view_ptr secondary_index_manager::create_view_for_index(const index_metadata& im
throw std::runtime_error(sprint("Unsupported index target type: %s", to_sstring(target_type)));
}
builder.with_column(index_target->name(), index_target->type, column_kind::partition_key);
// Additional token column is added to ensure token order on secondary index queries
bytes token_column_name = get_available_token_column_name(*schema);
builder.with_column(token_column_name, bytes_type, column_kind::clustering_key);
for (auto& col : schema->partition_key_columns()) {
if (col == *index_target) {
continue;

View File

@@ -42,8 +42,8 @@ SEASTAR_TEST_CASE(test_secondary_index_regular_column_query) {
return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
}).then([&e] (shared_ptr<cql_transport::messages::result_message> msg) {
assert_that(msg).is_rows().with_rows({
{ utf8_type->decompose(sstring("beassebyv@house.gov")) },
{ utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
{ utf8_type->decompose(sstring("beassebyv@house.gov")) },
});
});
});
@@ -65,8 +65,8 @@ SEASTAR_TEST_CASE(test_secondary_index_clustering_key_query) {
return e.execute_cql("SELECT email FROM users WHERE country = 'France';");
}).then([&e] (auto msg) {
assert_that(msg).is_rows().with_rows({
{ utf8_type->decompose(sstring("beassebyv@house.gov")) },
{ utf8_type->decompose(sstring("dcurrorw@techcrunch.com")) },
{ utf8_type->decompose(sstring("beassebyv@house.gov")) },
});
});
});
@@ -256,9 +256,7 @@ SEASTAR_TEST_CASE(test_many_columns) {
e.execute_cql("INSERT INTO tab (a, b, c, d, e, f) VALUES (0, 0, 0, 7, 0, 6)").get();
e.execute_cql("INSERT INTO tab (a, b, c, d, e, f) VALUES (1, 2, 3, 7, 5, 0)").get();
// We expect each search below to find two or three of the rows that
// we inserted above. NOTE: the order of the partitions we test below
// is the order which Scylla return today. We may need to change it
// in the future (see issue #3423).
// we inserted above.
BOOST_TEST_PASSPOINT();
eventually([&] {
auto res = e.execute_cql("SELECT * from tab WHERE a = 1").get0();
@@ -274,9 +272,9 @@ SEASTAR_TEST_CASE(test_many_columns) {
auto res = e.execute_cql("SELECT * from tab WHERE b = 2").get0();
assert_that(res).is_rows().with_size(3)
.with_rows({
{{int32_type->decompose(0)}, {int32_type->decompose(2)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}, {int32_type->decompose(5)}, {int32_type->decompose(6)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(7)}, {int32_type->decompose(5)}, {int32_type->decompose(0)}},
{{int32_type->decompose(0)}, {int32_type->decompose(2)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
});
});
BOOST_TEST_PASSPOINT();
@@ -284,9 +282,9 @@ SEASTAR_TEST_CASE(test_many_columns) {
auto res = e.execute_cql("SELECT * from tab WHERE c = 3").get0();
assert_that(res).is_rows().with_size(3)
.with_rows({
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(3)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}, {int32_type->decompose(5)}, {int32_type->decompose(6)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(7)}, {int32_type->decompose(5)}, {int32_type->decompose(0)}},
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(3)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
});
});
BOOST_TEST_PASSPOINT();
@@ -294,8 +292,8 @@ SEASTAR_TEST_CASE(test_many_columns) {
auto res = e.execute_cql("SELECT * from tab WHERE d = 4").get0();
assert_that(res).is_rows().with_size(2)
.with_rows({
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(4)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}, {int32_type->decompose(5)}, {int32_type->decompose(6)}},
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(4)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}},
});
});
BOOST_TEST_PASSPOINT();
@@ -303,9 +301,9 @@ SEASTAR_TEST_CASE(test_many_columns) {
auto res = e.execute_cql("SELECT * from tab WHERE e = 5").get0();
assert_that(res).is_rows().with_size(3)
.with_rows({
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(5)}, {int32_type->decompose(0)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}, {int32_type->decompose(5)}, {int32_type->decompose(6)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(7)}, {int32_type->decompose(5)}, {int32_type->decompose(0)}},
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(5)}, {int32_type->decompose(0)}},
});
});
BOOST_TEST_PASSPOINT();
@@ -313,8 +311,8 @@ SEASTAR_TEST_CASE(test_many_columns) {
auto res = e.execute_cql("SELECT * from tab WHERE f = 6").get0();
assert_that(res).is_rows().with_size(2)
.with_rows({
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(7)}, {int32_type->decompose(0)}, {int32_type->decompose(6)}},
{{int32_type->decompose(1)}, {int32_type->decompose(2)}, {int32_type->decompose(3)}, {int32_type->decompose(4)}, {int32_type->decompose(5)}, {int32_type->decompose(6)}},
{{int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(0)}, {int32_type->decompose(7)}, {int32_type->decompose(0)}, {int32_type->decompose(6)}},
});
});
});