Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

fix secondary index in get_kv_table_rows #9553

Merged
merged 2 commits into from
Oct 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2106,6 +2106,7 @@ read_only::get_table_rows_result read_only::get_kv_table_rows_context( const rea
abis.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time));

get_table_rows_result result;
uint32_t key_size;
uint32_t value_size;

auto cur_time = fc::time_point::now();
Expand All @@ -2132,6 +2133,15 @@ read_only::get_table_rows_result read_only::get_kv_table_rows_context( const rea
auto return_size = kv_context.kv_get_data(offset, value.data(), value_size);
EOS_ASSERT(return_size == value_size, chain::contract_table_query_exception, "point query value size mismatch: ${s1} ${s2}", ("s1", return_size)("s2", value_size));

if( !is_primary_idx) {
success = kv_context.kv_get(p.code.to_uint64_t(), value.data(), value.size(), value_size);
if (success) {
value.resize(value_size);
return_size = kv_context.kv_get_data(offset, value.data(), value_size);
EOS_ASSERT(return_size == value_size, chain::contract_table_query_exception, "point query value size mismatch: ${s1} ${s2}", ("s1", return_size)("s2", value_size));
}
}

fc::variant row_var;
if( p.json ) {
try {
Expand Down Expand Up @@ -2201,24 +2211,36 @@ read_only::get_table_rows_result read_only::get_kv_table_rows_context( const rea
// iterate the range
auto walk_table_row_range = [&]( auto &itr, auto &end_itr, bool reverse ) {
uint32_t actual_size = 0;
uint32_t key_size;
uint32_t val_size;

const vector<char> &end_key = (reverse ? lb_key : ub_key);
if( reverse ) {
key_size = ub_key_size;
val_size = ub_value_size;
value_size = ub_value_size;
} else {
key_size = lb_key_size;
val_size = lb_value_size;
value_size = lb_value_size;
}
auto cmp = itr->kv_it_key_compare(end_key.data(), end_key.size());
if( reverse ) cmp *= -1;

unsigned int count = 0;
for( count = 0; cur_time <= end_time && count < p.limit && cmp < 0; cur_time = fc::time_point::now() ) {
row_value.clear();
row_value.resize(val_size);
status = itr->kv_it_value(offset, row_value.data(), val_size, actual_size);
row_value.resize(value_size);
status = itr->kv_it_value(offset, row_value.data(), value_size, actual_size);
EOS_ASSERT(status_lb == chain::kv_it_stat::iterator_ok, chain::contract_table_query_exception, "Invalid key in ${t} ${i}", ("t", p.table)("i", p.index_name));

if (!is_primary_idx) {
std::swap(row_key, row_value);
auto success = kv_context.kv_get(p.code.to_uint64_t(), row_key.data(), row_key.size(), value_size);
if (success) {
row_value.resize(value_size);
actual_size = kv_context.kv_get_data(offset, row_value.data(), value_size);
EOS_ASSERT(value_size == actual_size, chain::contract_table_query_exception, "range query value size mismatch: ${s1} ${s2}", ("s1", value_size)("s2", actual_size));
} else {
EOS_ASSERT(false, chain::contract_table_query_exception, "range query failed to get data: ${t} ${i}", ("t", p.table)("i", p.index_name));
}
}

fc::variant row_var;
if( p.json ) {
Expand Down Expand Up @@ -2246,14 +2268,15 @@ read_only::get_table_rows_result read_only::get_kv_table_rows_context( const rea

cmp = itr->kv_it_key_compare(end_key.data(), end_key.size());
if( reverse ) cmp *= -1;
}
if( count == p.limit && cmp < 0 ) {
result.more = true;
row_key.resize(key_size);
auto status = itr->kv_it_key(0, row_key.data(), key_size, actual_size);
EOS_ASSERT(status != chain::kv_it_stat::iterator_erased && actual_size >= prefix_size(), chain::contract_table_query_exception, "Invalid lower bound iterator in ${t} ${i}", ("t", p.table)("i", p.index_name));
result.next_key = string(&row_key.data()[prefix_size()], row_key.size() - prefix_size());
}

if( count == p.limit && cmp < 0 ) {
result.more = true;
row_key.resize(key_size);
auto status = itr->kv_it_key(0, row_key.data(), key_size, value_size);
EOS_ASSERT(status != chain::kv_it_stat::iterator_erased && value_size >= prefix_size(), chain::contract_table_query_exception, "Invalid lower bound iterator in ${t} ${i}", ("t", p.table)("i", p.index_name));
result.next_key = string(&row_key.data()[prefix_size()], row_key.size() - prefix_size());
}
} // end of for
};

if( p.reverse ) {
Expand All @@ -2265,6 +2288,7 @@ read_only::get_table_rows_result read_only::get_kv_table_rows_context( const rea
return result;
}


read_only::get_table_by_scope_result read_only::get_table_by_scope( const read_only::get_table_by_scope_params& p )const {
read_only::get_table_by_scope_result result;
const auto& d = db.db();
Expand Down