12241 lines
489 KiB
C++
12241 lines
489 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <thread>
|
|
#define private public
|
|
#define protected public
|
|
#include "libobtable.h"
|
|
#include "lib/utility/ob_test_util.h"
|
|
#include "lib/allocator/page_arena.h"
|
|
#include "lib/lds/ob_lds_constructor.hpp"
|
|
#include "share/table/ob_table_rpc_struct.h"
|
|
#include "common/row/ob_row.h"
|
|
#include "observer/table/ob_htable_utils.h"
|
|
#include "observer/table/ob_htable_filter_operator.h"
|
|
#include "observer/table/ob_table_service.h"
|
|
#include "storage/ls/ob_ls_tablet_service.h"
|
|
#include <thread>
|
|
#undef private
|
|
#undef protected
|
|
using namespace oceanbase::common;
|
|
using namespace oceanbase::table;
|
|
|
|
// const char* host = "127.0.0.1";
|
|
// int32_t sql_port = 60809;
|
|
// int32_t rpc_port = 60808;
|
|
const char* host = "127.0.0.1";
|
|
int32_t sql_port = 41101;
|
|
int32_t rpc_port = 41100;
|
|
const char* tenant = "sys";
|
|
const char* user_name = "root";
|
|
const char* passwd = "";
|
|
const char* db = "test";
|
|
const char* table_name = "batch_execute_test";
|
|
const char* sys_root_pass = "";
|
|
typedef char DefaultBuf[128];
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace storage
|
|
{
|
|
int ObLSTabletService::check_parts_tx_state_in_transfer_for_4377_(transaction::ObTxDesc *)
|
|
{
|
|
return OB_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
// create table if not exists batch_execute_test (C1 bigint primary key, C2 bigint, C3 varchar(100)) PARTITION BY KEY(C1) PARTITIONS 16
|
|
class TestBatchExecute: public ::testing::Test
|
|
{
|
|
public:
|
|
TestBatchExecute();
|
|
virtual ~TestBatchExecute();
|
|
virtual void SetUp();
|
|
virtual void TearDown();
|
|
private:
|
|
// disallow copy
|
|
DISALLOW_COPY_AND_ASSIGN(TestBatchExecute);
|
|
protected:
|
|
// function members
|
|
void generate_get(ObTableQuery &query, ObObj pk_objs_start[], ObObj pk_objs_end[], const char* rowkey);
|
|
void prepare_data(ObTable *the_table);
|
|
protected:
|
|
static const int64_t BATCH_SIZE;
|
|
ObTableServiceClient* service_client_ = NULL;
|
|
ObTable* table_ = NULL;
|
|
};
|
|
|
|
const int64_t TestBatchExecute::BATCH_SIZE = 100;
|
|
TestBatchExecute::TestBatchExecute()
|
|
{
|
|
}
|
|
|
|
TestBatchExecute::~TestBatchExecute()
|
|
{
|
|
}
|
|
|
|
void TestBatchExecute::SetUp()
|
|
{
|
|
ASSERT_TRUE(NULL == service_client_);
|
|
service_client_ = ObTableServiceClient::alloc_client();
|
|
ASSERT_TRUE(NULL != service_client_);
|
|
int ret = service_client_->init(ObString::make_string(host), sql_port, rpc_port,
|
|
ObString::make_string(tenant), ObString::make_string(user_name),
|
|
ObString::make_string(passwd), ObString::make_string(db),
|
|
ObString::make_string(sys_root_pass));
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ret = service_client_->alloc_table(ObString::make_string(table_name), table_);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableRequestOptions options;
|
|
options.set_returning_affected_rows(true);
|
|
//options.set_consistency_level(ObTableConsistencyLevel::EVENTUAL);
|
|
table_->set_default_request_options(options);
|
|
}
|
|
|
|
void TestBatchExecute::TearDown()
|
|
{
|
|
service_client_->free_table(table_);
|
|
table_ = NULL;
|
|
ObTableServiceClient::free_client(service_client_);
|
|
service_client_ = NULL;
|
|
}
|
|
|
|
|
|
ObString C1 = ObString::make_string("C1");
|
|
ObString C2 = ObString::make_string("C2");
|
|
ObString C3 = ObString::make_string("C3");
|
|
ObString K = ObString::make_string("K");
|
|
ObString Q = ObString::make_string("Q");
|
|
ObString T = ObString::make_string("T");
|
|
ObString V = ObString::make_string("V");
|
|
ObString PK1 = ObString::make_string("PK1");
|
|
ObString PK2 = ObString::make_string("PK2");
|
|
|
|
void TestBatchExecute::generate_get(ObTableQuery &query, ObObj pk_objs_start[], ObObj pk_objs_end[], const char* rowkey)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
|
|
pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
}
|
|
|
|
void TestBatchExecute::prepare_data(ObTable *the_table)
|
|
{
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
switch (i % 4) {
|
|
case 0:
|
|
value.set_varbinary(ObString::make_string("string2"));
|
|
break;
|
|
case 1:
|
|
value.set_varbinary(ObString::make_string("string3"));
|
|
break;
|
|
case 2: // row50
|
|
value.set_varbinary(ObString::make_string("string0"));
|
|
break;
|
|
case 3:
|
|
value.set_varbinary(ObString::make_string("string1"));
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(1, result.count());
|
|
ASSERT_EQ(OB_SUCCESS, result.at(0).get_errno());
|
|
delete [] rows;
|
|
}
|
|
|
|
|
|
TEST_F(TestBatchExecute, entity_factory)
|
|
{
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
static const int64_t N = 100;
|
|
static const int64_t R = 3;
|
|
for (int round = 0; round < R; ++round) {
|
|
|
|
for (int i = 0; i < N; ++i)
|
|
{
|
|
ObITableEntity *entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
} // end for
|
|
fprintf(stderr, "used=%ld free=%ld mem_total=%ld mem_used=%ld\n",
|
|
entity_factory.get_used_count(), entity_factory.get_free_count(),
|
|
entity_factory.get_total_mem(), entity_factory.get_used_mem());
|
|
entity_factory.free_and_reuse();
|
|
fprintf(stderr, "used=%ld free=%ld mem_total=%ld mem_used=%ld\n",
|
|
entity_factory.get_used_count(), entity_factory.get_free_count(),
|
|
entity_factory.get_total_mem(), entity_factory.get_used_mem());
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, serialize_batch_result)
|
|
{
|
|
ObTableBatchOperationResult result;
|
|
ObTableEntity result_entity;
|
|
ObTableOperationResult single_op_result;
|
|
single_op_result.set_entity(result_entity);
|
|
single_op_result.set_errno(1234);
|
|
single_op_result.set_type(ObTableOperationType::INSERT_OR_UPDATE);
|
|
single_op_result.set_affected_rows(4321);
|
|
ASSERT_EQ(OB_SUCCESS, result.push_back(single_op_result));
|
|
int64_t expected_len = result.get_serialize_size();
|
|
char buf[1024];
|
|
int64_t pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, result.serialize(buf, 1024, pos));
|
|
ASSERT_EQ(expected_len, pos);
|
|
|
|
ObTableBatchOperationResult result2;
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
result2.set_entity_factory(&entity_factory);
|
|
int64_t data_len = pos;
|
|
//fprintf(stderr, "yzfdebug datalen=%ld expectedlen=%ld\n", data_len, expected_len);
|
|
pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, result2.deserialize(buf, data_len, pos));
|
|
ASSERT_EQ(1, result2.count());
|
|
ASSERT_EQ(1234, result2.at(0).get_errno());
|
|
ASSERT_EQ(4321, result2.at(0).get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, result2.at(0).type());
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestBatchExecute, all_single_operation)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("all_single_operation_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
OB_LOG(INFO, "begin all_single_operation");
|
|
// insert C2
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
// insert again: fail
|
|
{
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
}
|
|
// update C3
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
// update C3 not exist key
|
|
{
|
|
entity->reset();
|
|
ObObj not_exist_key;
|
|
not_exist_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(not_exist_key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// update rowkey column
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C1, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_NOT_SUPPORTED, table_->execute(table_operation, r));
|
|
}
|
|
// replace C3
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
// insert_or_update C2: update
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
// delete not exist row
|
|
{
|
|
entity->reset();
|
|
ObObj not_exist_key;
|
|
not_exist_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(not_exist_key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// delete
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get again
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// insert_or_update C2: insert
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
}
|
|
// delete & cleanup
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, multi_insert_or_update_AND_multi_get)
|
|
{
|
|
OB_LOG(INFO, "begin multi_insert_or_update");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("batch_execute_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// get and verify
|
|
const ObITableEntity *result_entity = NULL;
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
}
|
|
}
|
|
// multi-get case 2
|
|
{
|
|
ObObj null_obj;
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = BATCH_SIZE-1; i >= 0; --i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_retrieve_property(C2));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
if (i % 2 == 1) {
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
//fprintf(stderr, "get value i=%ld v=%s\n", i, S(value));
|
|
ASSERT_EQ(100+(BATCH_SIZE-1-i)/2, value.get_int());
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// create table type_check_test (pk1 bigint, pk2 varchar(10), ctinyint tinyint, csmallint smallint, cmediumint mediumint, cint int, cbigint bigint, utinyint tinyint unsigned, usmallint smallint unsigned, uint int unsigned, ubigint bigint unsigned, cfloat float, cdouble double, ufloat float unsigned, udouble double unsigned, cnumber decimal(10, 2), unumber decimal(10,2) unsigned, cvarchar varchar(10), cchar char(10), cbinary binary(10), cvarbinary varbinary(10), ctimestamp timestamp, cdatetime datetime, cyear year, cdate date, ctime time, ctext text, cblob blob, cbit bit(64), cnotnull bigint not null, primary key(pk1, pk2));
|
|
ObString CTINYINT = ObString::make_string("ctinyint");
|
|
ObString CNOTNULL = ObString::make_string("cnotnull");
|
|
TEST_F(TestBatchExecute, column_type_check)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("type_check_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
// case for insert operation
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
|
|
int64_t pk1_value = 139107;
|
|
ObString pk2_value = ObString::make_string("helloss");
|
|
ObTableOperationResult r;
|
|
|
|
ObObj pk1, pk2, value;
|
|
{
|
|
// case: insert + rowkey + null
|
|
entity->reset();
|
|
pk1.set_null();
|
|
pk2.set_varchar(pk2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_BAD_NULL_ERROR, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + rowkey + int
|
|
entity->reset();
|
|
pk1.set_int32(111);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLUMN_TYPE_NOT_MATCH, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + rowkey + too long
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(ObString::make_string("a very loooooooooooooooooooooooooog string"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + not null
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_null();
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CNOTNULL, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_BAD_NULL_ERROR, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + ufloat out of range
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_ufloat(-1.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ufloat"), value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_DATA_OUT_OF_RANGE, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert + mediumint out of range
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_mediumint(INT32_MAX);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cmediumint"), value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_DATA_OUT_OF_RANGE, r.get_errno());
|
|
}
|
|
{
|
|
// case: insert succ
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
|
|
value.set_tinyint(-8);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ctinyint"), value));
|
|
value.set_smallint(-88);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("csmallint"), value));
|
|
value.set_mediumint(-888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cmediumint"), value));
|
|
value.set_int32(-8888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cint"), value));
|
|
value.set_int(-88888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cbigint"), value));
|
|
|
|
value.set_utinyint(8);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("utinyint"), value));
|
|
value.set_usmallint(88);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("usmallint"), value));
|
|
value.set_umediumint(888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("umediumint"), value));
|
|
value.set_uint32(8888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("uint"), value));
|
|
value.set_uint64(88888);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ubigint"), value));
|
|
|
|
value.set_ufloat(1.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ufloat"), value));
|
|
value.set_float(-1.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cfloat"), value));
|
|
value.set_udouble(1.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("udouble"), value));
|
|
value.set_double(-1.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cdouble"), value));
|
|
|
|
value.set_char(pk2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cbinary"), value));
|
|
value.set_varbinary(pk2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cvarbinary"), value));
|
|
value.set_char(pk2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cchar"), value));
|
|
value.set_varchar(pk2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cvarchar"), value));
|
|
|
|
value.set_string(ObTextType, pk2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ctext"), value));
|
|
value.set_string(ObTextType, pk2_value);
|
|
value.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cblob"), value));
|
|
|
|
int64_t now = ObTimeUtility::current_time();
|
|
ObTimeConverter::round_datetime(0, now);
|
|
value.set_timestamp(now);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ctimestamp"), value));
|
|
value.set_datetime(now);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cdatetime"), value));
|
|
value.set_year(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cyear"), value));
|
|
value.set_date(30);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cdate"), value));
|
|
value.set_time(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("ctime"), value));
|
|
|
|
value.set_bit(8);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cbit"), value));
|
|
// cnotnull not specified and inserted as default value
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// other type of operations
|
|
////////////////////////////////////////////////////////////////
|
|
{
|
|
// case: get + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
{
|
|
// case: replace + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: replace + mediumint out of range
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_mediumint(INT32_MAX);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cmediumint"), value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_DATA_OUT_OF_RANGE, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: insert_or_update + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: insertup + mediumint out of range
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_mediumint(INT32_MAX);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cmediumint"), value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_DATA_OUT_OF_RANGE, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: delete + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
{
|
|
// case: update + rowkey + collation
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_BINARY);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_int(100);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(CTINYINT, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: update + mediumint out of range
|
|
entity->reset();
|
|
pk1.set_int(pk1_value);
|
|
pk2.set_varchar(pk2_value);
|
|
pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
value.set_mediumint(INT32_MAX);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cmediumint"), value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_DATA_OUT_OF_RANGE, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: insert_or_update varbinary -> blob
|
|
// TODO (luohongdi.lhd): Fix it when lob ready
|
|
// entity->reset();
|
|
// pk1.set_int(pk1_value);
|
|
// pk2.set_varchar(pk2_value);
|
|
// pk2.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
//
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk2));
|
|
// value.set_string(ObVarcharType, ObString::make_string("cblob value"));
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(ObString::make_string("cblob"), value));
|
|
// ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
}
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, column_default_value)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("column_default_value"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
// case for insert operation
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
ObTableOperationResult r;
|
|
{
|
|
// case: insert + rowkey
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
|
|
int64_t pk1_value = 139107;
|
|
ObObj pk1;
|
|
pk1.set_int(pk1_value);
|
|
ObObj value;
|
|
value.set_int(pk1_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(pk1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, serialize_table_query)
|
|
{
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_int(0);
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
int64_t serialize_len = query.get_serialize_size();
|
|
fprintf(stderr, "serialize_size=%ld\n", serialize_len);
|
|
char buf[1024];
|
|
int64_t pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, query.serialize(buf, 1024, pos));
|
|
ASSERT_EQ(pos, serialize_len);
|
|
|
|
ObTableQuery query2;
|
|
ObArenaAllocator alloc;
|
|
query2.set_deserialize_allocator(&alloc);
|
|
pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, query2.deserialize(buf, serialize_len, pos));
|
|
const ObIArray<ObString> &select_columns = query2.get_select_columns();
|
|
const ObIArray<ObNewRange> &scan_ranges = query2.get_scan_ranges();
|
|
ASSERT_EQ(3, select_columns.count());
|
|
ASSERT_EQ(1, scan_ranges.count());
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, serialize_query_result)
|
|
{
|
|
ObTableQueryResult query_result;
|
|
ObObj objs[3];
|
|
objs[0].set_int(123);
|
|
objs[1].set_null();
|
|
objs[2].set_varchar(ObString::make_string("serialize_query_result"));
|
|
ObNewRow row;
|
|
row.assign(objs, 3);
|
|
ASSERT_EQ(OB_SUCCESS, query_result.add_property_name(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query_result.add_property_name(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query_result.add_property_name(C3));
|
|
for (int64_t i = 0; i < 1024; ++i) {
|
|
ASSERT_EQ(OB_SUCCESS, query_result.add_row(row));
|
|
}
|
|
ASSERT_EQ(1024, query_result.get_row_count());
|
|
ASSERT_EQ(3, query_result.get_property_count());
|
|
// serialize
|
|
char *buf = static_cast<char*>(ob_malloc(OB_MALLOC_BIG_BLOCK_SIZE, ObModIds::TEST));
|
|
ASSERT_TRUE(nullptr != buf);
|
|
int64_t pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, query_result.serialize(buf, OB_MALLOC_BIG_BLOCK_SIZE, pos));
|
|
ASSERT_EQ(pos, query_result.get_serialize_size());
|
|
fprintf(stderr, "serialize_size=%ld\n", pos);
|
|
// deserialize & check
|
|
ObTableQueryResult query_result2;
|
|
int64_t data_len = pos;
|
|
pos = 0;
|
|
ASSERT_EQ(OB_SUCCESS, query_result2.deserialize(buf, data_len, pos));
|
|
ASSERT_EQ(1024, query_result2.get_row_count());
|
|
ASSERT_EQ(3, query_result2.get_property_count());
|
|
const ObITableEntity *entity = NULL;
|
|
for (int64_t i = 0; i < 1024; ++i) {
|
|
ASSERT_EQ(OB_SUCCESS, query_result2.get_next_entity(entity));
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(3, entity->get_properties_count());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, entity->get_property(C1, value));
|
|
ASSERT_EQ(123, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == ObString::make_string("serialize_query_result"));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, query_result2.get_next_entity(entity));
|
|
// cleanup
|
|
if (NULL != buf) {
|
|
ob_free(buf);
|
|
buf = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// create table if not exists partial_update_test (C1 bigint primary key, C2 bigint, C3 varchar(100) not null);
|
|
TEST_F(TestBatchExecute, partial_update)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("partial_update_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
//prepare data
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1235);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
|
|
//single update
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1245);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//insert or update
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(5432);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//batch update
|
|
const int64_t batch_size = 2;
|
|
ObTableBatchOperation batch_operation;
|
|
for (int64_t i = 0; i < batch_size; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
key.set_int(key_key + i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.update(*entity));
|
|
}
|
|
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(batch_size, result.count());
|
|
for (int64_t i = 0; i < batch_size; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
} // end for
|
|
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
|
|
// create table if not exists append_lob_test (C1 bigint primary key, C2 bigint, C3 mediumtext not null);
|
|
TEST_F(TestBatchExecute, append_lob)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("append_lob_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
//prepare data
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1235);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//append small
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::append(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, value));
|
|
ASSERT_EQ(key_key, value.get_int());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello worldhello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
ASSERT_EQ(CS_TYPE_UTF8MB4_GENERAL_CI, value.get_collation_type());
|
|
}
|
|
|
|
//append big
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
const int32_t big_value_len = 3 * 1024 * 1024;
|
|
char *big_value = (char*) malloc(big_value_len);
|
|
ASSERT_TRUE(NULL != big_value);
|
|
memset(big_value, 'A', big_value_len);
|
|
ObString c3_big_value(big_value_len, big_value);
|
|
|
|
ObObj val;
|
|
val.set_varchar(c3_big_value);
|
|
val.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, val));
|
|
table_operation = ObTableOperation::append(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
// TODO:@linjing concat还未支持大对象,待修复到master后patch到特性分支
|
|
ASSERT_EQ(OB_SIZE_OVERFLOW, the_table->execute(table_operation, req_options, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// ASSERT_TRUE(!result_entity->is_empty());
|
|
// ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, val));
|
|
// ASSERT_EQ(key_key, val.get_int());
|
|
// ASSERT_EQ(1, result_entity->get_properties_count());
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, val));
|
|
// ASSERT_EQ(CS_TYPE_UTF8MB4_GENERAL_CI, val.get_collation_type());
|
|
|
|
if (NULL != big_value) {
|
|
free(big_value);
|
|
big_value = NULL;
|
|
}
|
|
}
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// for lob column
|
|
// drop table if exists all_lob_test; create table if not exists all_lob_test (C1 bigint primary key, C2 bigint, C3 mediumtext, index i1(c2) local)
|
|
// TEST_F(TestBatchExecute, lob_column_test)
|
|
// {
|
|
// // setup
|
|
// ObTable *the_table = NULL;
|
|
// int ret = service_client_->alloc_table(ObString::make_string("all_lob_test"), the_table);
|
|
// ASSERT_EQ(OB_SUCCESS, ret);
|
|
// ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
// ObTableOperationResult r;
|
|
// ObITableEntity *entity = NULL;
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ObTableOperation table_operation;
|
|
// // k,v
|
|
// ObObj key;
|
|
// ObObj value;
|
|
// int64_t key_key = 139107;
|
|
// int64_t value_value = 33521;
|
|
// // small value
|
|
// ObString c3_value = ObString::make_string("hello world");
|
|
// // big value
|
|
// const int32_t big_value_len = 3 * 1024 * 1024;
|
|
// char *big_value = (char*) malloc(big_value_len);
|
|
// ASSERT_TRUE(NULL != big_value);
|
|
// memset(big_value, 'A', big_value_len);
|
|
// ObString c3_big_value(big_value_len, big_value);
|
|
// entity = entity_factory.alloc();
|
|
// {
|
|
// // insert small value
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// key.set_int(key_key);
|
|
// value.set_int(value_value);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::insert(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// // insert big value
|
|
// entity->reset();
|
|
// key.set_int(key_key + 1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_int(1235);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
// value.set_varchar(c3_big_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::insert(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// }
|
|
// {
|
|
// // delete small value
|
|
// entity->reset();
|
|
// key.set_int(key_key);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// table_operation = ObTableOperation::del(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
// // delete big value
|
|
// entity->reset();
|
|
// key.set_int(key_key + 1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// table_operation = ObTableOperation::del(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
// }
|
|
// {
|
|
// // replace small value
|
|
// entity->reset();
|
|
// key.set_int(key_key);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ObString c3_new_value = ObString::make_string("rere hello world");
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::append(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
// //replace big
|
|
// entity->reset();
|
|
// key.set_int(key_key+1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_varchar(c3_big_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::append(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
// }
|
|
// {
|
|
// // update small value
|
|
// entity->reset();
|
|
// key.set_int(key_key);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ObString c3_new_value = ObString::make_string("upup hello world");
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::update(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
// //update big value
|
|
// entity->reset();
|
|
// key.set_int(key_key+1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_varchar(c3_big_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::update(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
// }
|
|
// {
|
|
// // insert_up small value
|
|
// entity->reset();
|
|
// key.set_int(key_key);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_int(value_value+1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
// ObString c3_new_value = ObString::make_string("final hello world");
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::insert_or_update(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
// //insert_up big value
|
|
// entity->reset();
|
|
// key.set_int(key_key+1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_varchar(c3_big_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::insert_or_update(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
// }
|
|
// {
|
|
// // get small value
|
|
// ObObj null_obj;
|
|
// entity->reset();
|
|
// key.set_int(key_key);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
// table_operation = ObTableOperation::retrieve(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// result_entity = NULL;
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(0, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
// ASSERT_EQ(2, result_entity->get_properties_count());
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
// ASSERT_EQ(value_value+1,value.get_int());
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
// ObString str;
|
|
// ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
// ASSERT_TRUE(str.case_compare("final hello world"));
|
|
// // get big value
|
|
// entity->reset();
|
|
// key.set_int(key_key+1);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
// table_operation = ObTableOperation::retrieve(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// result_entity = NULL;
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(0, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
// ASSERT_EQ(1, result_entity->get_properties_count());
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
// ObString str2;
|
|
// ASSERT_EQ(OB_SUCCESS, value.get_varchar(str2));
|
|
// ASSERT_TRUE(c3_big_value == str2);
|
|
// }
|
|
|
|
// if (NULL != big_value) {
|
|
// free(big_value);
|
|
// big_value = NULL;
|
|
// }
|
|
// // teardown
|
|
// service_client_->free_table(the_table);
|
|
// the_table = NULL;
|
|
// }
|
|
|
|
// create table if not exists virtual_generate_col_test
|
|
// (C1 bigint primary key, C2 bigint, C3 varchar(100),
|
|
// C3_PREFIX varchar(10) GENERATED ALWAYS AS (substr(C3,1,2)));
|
|
TEST_F(TestBatchExecute, virtual_generate_col_test)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("virtual_generate_col_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
ObString C3_PREFIX = ObString::make_string("C3_PREFIX");
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
//prepare data insert
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//get and check
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3_PREFIX, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3_PREFIX, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("he");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
|
|
//update and check
|
|
c3_value = ObString::make_string("test hello");
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3_PREFIX, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3_PREFIX, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
c3_new_value = ObString::make_string("te");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
|
|
// delete & cleanup
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists store_generate_col_test
|
|
// (c1 bigint primary key, c2 varchar(10), c3 varchar(10),
|
|
// gen varchar(30) generated always as (concat(c2,c3)) stored)
|
|
TEST_F(TestBatchExecute, stored_generate_col_test)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("store_generate_col_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
ObString GEN = ObString::make_string("gen");
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 1;
|
|
ObObj key;
|
|
ObObj value;
|
|
|
|
//prepare data insert
|
|
ObString c2_value = ObString::make_string("hello");
|
|
ObString c3_value = ObString::make_string("world");
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//get and check
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(GEN, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(GEN, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString gen_new_value = ObString::make_string("helloworld");
|
|
ASSERT_TRUE(str == gen_new_value);
|
|
|
|
//update and check
|
|
c3_value = ObString::make_string("oceanbase");
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(GEN, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(GEN, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
gen_new_value = ObString::make_string("hellooceanbase");
|
|
ASSERT_TRUE(str == gen_new_value);
|
|
|
|
// insert or update (insert)
|
|
c3_value = ObString::make_string("world");
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
//get and check
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(GEN, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(GEN, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
gen_new_value = ObString::make_string("helloworld");
|
|
ASSERT_TRUE(str == gen_new_value);
|
|
|
|
// insert or update (update)
|
|
c2_value = ObString::make_string("oceanbase");
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
//get and check
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(GEN, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(GEN, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
gen_new_value = ObString::make_string("oceanbaseworld");
|
|
ASSERT_TRUE(str == gen_new_value);
|
|
|
|
// delete & cleanup
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists large_scan_test (C1 bigint primary key, C2 bigint, C3 varchar(100));
|
|
// TEST_F(TestBatchExecute, large_scan)
|
|
// {
|
|
// // setup
|
|
// ObTable *the_table = NULL;
|
|
// int ret = service_client_->alloc_table(ObString::make_string("large_scan_test"), the_table);
|
|
// ASSERT_EQ(OB_SUCCESS, ret);
|
|
// ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
// ObTableOperationResult r;
|
|
// ObITableEntity *entity = NULL;
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ObTableOperation table_operation;
|
|
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// int64_t key_key = 139107;
|
|
// ObObj key;
|
|
// key.set_int(key_key);
|
|
// int64_t value_value = 33521;
|
|
// ObObj value;
|
|
// value.set_int(value_value);
|
|
|
|
// //prepare data
|
|
// const int64_t large_batch_size = 10000;
|
|
// ObString c3_value = ObString::make_string("hello world");
|
|
// for (int64_t i = 0; i < large_batch_size; ++i) {
|
|
// entity->reset();
|
|
// key.set_int(key_key + i);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_int(value_value);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// table_operation = ObTableOperation::insert(*entity);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// }
|
|
// entity->reset();
|
|
|
|
// //scan
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
// ObObj pk_objs_start;
|
|
// pk_objs_start.set_int(0);
|
|
// ObObj pk_objs_end;
|
|
// pk_objs_end.set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(&pk_objs_start, 1);
|
|
// range.end_key_.assign(&pk_objs_end, 1);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// query.set_scan_index(ObString::make_string("primary"));
|
|
// query.set_scan_order(ObQueryFlag::Forward);
|
|
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// int64_t result_cnt = 0;
|
|
// while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
// result_cnt++;
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, ret);
|
|
// ASSERT_EQ(result_cnt, large_batch_size);
|
|
|
|
// //reverse scan
|
|
// query.set_scan_order(ObQueryFlag::Reverse);
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// result_cnt = 0;
|
|
// while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
// result_cnt++;
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, ret);
|
|
// ASSERT_EQ(result_cnt, large_batch_size);
|
|
|
|
// //large batch append
|
|
// {
|
|
// int64_t append_batch_size = 10;
|
|
// ObTableBatchOperation batch_operation;
|
|
// for (int64_t i = 0; i < append_batch_size; ++i) {
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// key.set_int(key_key + i);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// value.set_varchar(c3_value);
|
|
// value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.append(*entity));
|
|
// }
|
|
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
// OB_LOG(INFO, "batch execute result", K(result));
|
|
// ASSERT_EQ(append_batch_size, result.count());
|
|
// for (int64_t i = 0; i < append_batch_size; ++i)
|
|
// {
|
|
// const ObTableOperationResult &r = result.at(i);
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// } // end for
|
|
// }
|
|
|
|
// // teardown
|
|
// service_client_->free_table(the_table);
|
|
// the_table = NULL;
|
|
// }
|
|
|
|
|
|
// create table if not exists uniq_replace_test (C1 bigint primary key, C2 bigint, C3 varchar(100), unique key C2_UNIQ(C2));
|
|
TEST_F(TestBatchExecute, uniq_replace)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("uniq_replace_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
//prepare data
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1235);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
|
|
//replace
|
|
entity->reset();
|
|
key.set_int(key_key + 2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1236);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
c3_value = ObString::make_string("hello china");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//replace uniq
|
|
entity->reset();
|
|
key.set_int(key_key + 3);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1236);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
c3_value = ObString::make_string("hello everyone");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
//@TODO: table_api::replace need to return affected_rows=2 here,
|
|
//but table api not maintain local index here, so affected_rows is 1
|
|
//need to fix me
|
|
ASSERT_EQ(2, r.get_affected_rows());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
|
|
//insert or update, uniq key conflict, not support now
|
|
/*
|
|
entity->reset();
|
|
key.set_int(key_key + 4);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(1236);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
c3_value = ObString::make_string("hello everyone");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_NE(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
*/
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
|
|
|
|
// create table if not exists execute_query_test (PK1 bigint, PK2 bigint, C1 bigint, C2 varchar(100), C3 bigint, PRIMARY KEY(PK1, PK2), INDEX idx1(C1, C2));
|
|
TEST_F(TestBatchExecute, query_pk_prefix)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("execute_query_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i%5);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C1, value));
|
|
value.set_varchar(ObString::make_string("c2_value"));
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// cases
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(PK2));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_int(0);
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_offset(5);
|
|
query.set_limit(10);
|
|
query.set_scan_index(ObString::make_string("primary"));
|
|
ObQueryFlag::ScanOrder scan_orders[2] = { ObQueryFlag::Forward, ObQueryFlag::Reverse };
|
|
for (int k = 0; k < 2; ++k)
|
|
{
|
|
// two scan order
|
|
query.set_scan_order(scan_orders[k]);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
for (int64_t i = 5; i < 15; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(4, result_entity->get_properties_count());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, value));
|
|
if (0 == k) {
|
|
ASSERT_EQ(100+i*5, value.get_int());
|
|
} else {
|
|
ASSERT_EQ(100+(19-i)*5, value.get_int());
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == ObString::make_string("c2_value"));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(PK2, value));
|
|
if (0 == k) {
|
|
ASSERT_EQ(i*5, value.get_int());
|
|
} else {
|
|
ASSERT_EQ((19-i)*5, value.get_int());
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
} // end for
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, compare_cell)
|
|
{
|
|
ObObj row1_objs[4];
|
|
ObNewRow row1(row1_objs, 4);
|
|
ObHTableCellEntity cell1(&row1);
|
|
ObObj row2_objs[4];
|
|
ObNewRow row2(row2_objs, 4);
|
|
ObHTableCellEntity cell2(&row2);
|
|
oceanbase::common::ObQueryFlag::ScanOrder scan_order = ObQueryFlag::Forward;
|
|
// case 1
|
|
row1_objs[ObHTableConstants::COL_IDX_K].set_varchar(ObString::make_string("abc"));
|
|
row1_objs[ObHTableConstants::COL_IDX_Q].set_varchar(ObString::make_string(""));
|
|
row1_objs[ObHTableConstants::COL_IDX_T].set_int(-2);
|
|
row1_objs[ObHTableConstants::COL_IDX_V].set_varchar(ObString::make_string("value1"));
|
|
row2_objs[ObHTableConstants::COL_IDX_K].set_varchar(ObString::make_string("abc"));
|
|
row2_objs[ObHTableConstants::COL_IDX_Q].set_varchar(ObString::make_string(""));
|
|
row2_objs[ObHTableConstants::COL_IDX_T].set_int(-2);
|
|
row2_objs[ObHTableConstants::COL_IDX_V].set_varchar(ObString::make_string("value2"));
|
|
ASSERT_EQ(0, ObHTableUtils::compare_cell(cell1, cell2, scan_order));
|
|
// case 1: compare timestamp
|
|
row2_objs[ObHTableConstants::COL_IDX_T].set_int(-3);
|
|
ASSERT_EQ(1, ObHTableUtils::compare_cell(cell1, cell2, scan_order));
|
|
row1_objs[ObHTableConstants::COL_IDX_T].set_int(-4);
|
|
ASSERT_EQ(-1, ObHTableUtils::compare_cell(cell1, cell2, scan_order));
|
|
row1_objs[ObHTableConstants::COL_IDX_Q].set_varchar(ObString::make_string("c1"));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell1, cell2, scan_order) > 0);
|
|
// case 2: last on row
|
|
ObHTableLastOnRowCell last_on_row(ObString::make_string("abc"));
|
|
ASSERT_EQ(-1, ObHTableUtils::compare_cell(cell1, last_on_row, scan_order));
|
|
ASSERT_EQ(-1, ObHTableUtils::compare_cell(cell2, last_on_row, scan_order));
|
|
ASSERT_EQ(1, ObHTableUtils::compare_cell(last_on_row, cell1, scan_order));
|
|
ASSERT_EQ(1, ObHTableUtils::compare_cell(last_on_row, cell2, scan_order));
|
|
// case 3: last on column
|
|
ObHTableLastOnRowColCell last_on_col(ObString::make_string("abc"), ObString::make_string(""));
|
|
ASSERT_EQ(-1, ObHTableUtils::compare_cell(cell2, last_on_col, scan_order));
|
|
ASSERT_EQ(1, ObHTableUtils::compare_cell(last_on_col, cell2, scan_order));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell1, last_on_col, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_col, cell1, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_col, last_on_row, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_row, last_on_col, scan_order) > 0);
|
|
ObHTableLastOnRowColCell last_on_col2(ObString::make_string("abc"), ObString::make_string(""));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_col, last_on_col2, scan_order) == 0);
|
|
// case 4: first on row
|
|
ObHTableFirstOnRowCell first_on_row(ObString::make_string("abc"));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell1, first_on_row, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell2, first_on_row, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_row, cell1, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_row, cell2, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_row, last_on_col, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_col, first_on_row, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_row, last_on_row, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_row, first_on_row, scan_order) > 0);
|
|
// case 5: first on column
|
|
ObHTableFirstOnRowColCell first_on_col(ObString::make_string("abc"), ObString::make_string(""));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell2, first_on_col, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, cell2, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell1, first_on_col, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, cell1, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, first_on_row, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_row, first_on_col, scan_order) < 0);
|
|
ObHTableFirstOnRowColCell first_on_col2(ObString::make_string("abc"), ObString::make_string(""));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, first_on_col2, scan_order) == 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, last_on_col, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_col, first_on_col, scan_order) > 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(first_on_col, last_on_row, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(last_on_row, first_on_col, scan_order) > 0);
|
|
// case 6: compare rowkey
|
|
row2_objs[ObHTableConstants::COL_IDX_K].set_varchar(ObString::make_string("abc1"));
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell1, cell2, scan_order) < 0);
|
|
ASSERT_TRUE(ObHTableUtils::compare_cell(cell2, cell1, scan_order) > 0);
|
|
}
|
|
|
|
// create table htable1_cf1 (K varbinary(1024), Q varbinary(256), T bigint, V varbinary(1024), primary key(K, Q, T)) partition by key(K) partitions 16;
|
|
TEST_F(TestBatchExecute, htable_scan_basic)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("value_string"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// htable filter cases
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
ObObj pk_objs_start[3];
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
ObObj pk_objs_end[3];
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row59"));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[6] = {0, 3, 1, 4, 7, 9};
|
|
for (int i = 0; OB_SUCCESS == ret && i < 6; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
// Case 0
|
|
fprintf(stderr, "Case 0: without max version or time range\n");
|
|
{
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// Case 1
|
|
fprintf(stderr, "Case 1: with max version and time range\n");
|
|
{
|
|
htable_filter.set_max_versions(2);
|
|
htable_filter.set_time_range(3, 8);
|
|
htable_filter.set_row_offset_per_column_family(2);
|
|
htable_filter.set_max_results_per_column_family(8);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
fprintf(stderr, "Case 2: set max version only\n");
|
|
{
|
|
htable_filter.set_max_versions(5);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
htable_filter.set_row_offset_per_column_family(0);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9, 8, 7, 6, 5};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
fprintf(stderr, "Case 3: multiple result packet\n");
|
|
{
|
|
htable_filter.set_max_versions(1);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
htable_filter.set_row_offset_per_column_family(0);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
query.set_batch(3);
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
fprintf(stderr, "Case 5: Wildcard column tracker\n");
|
|
{
|
|
htable_filter.set_max_versions(5);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, 8);
|
|
htable_filter.set_row_offset_per_column_family(5);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
htable_filter.clear_columns();
|
|
query.set_batch(-1);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
int64_t timestamps[] = {7, 6, 5, 4, 3};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
//fprintf(stderr, "i=%ld\n", i);
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_scan_reverse)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_reverse"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("value_string"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// htable filter cases
|
|
ObTableQuery query;
|
|
query.set_scan_order(ObQueryFlag::Reverse);
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
ObObj pk_objs_start[3];
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
ObObj pk_objs_end[3];
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row59"));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[6] = {0, 3, 1, 4, 7, 9};
|
|
for (int i = 0; OB_SUCCESS == ret && i < 6; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
// Case 0
|
|
fprintf(stderr, "Case 0: reverse scan without max version or time range\n");
|
|
{
|
|
ObTableEntityIterator *iter = nullptr;
|
|
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0, m = 59; i < 10; ++i, --m) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", m);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
|
|
for (int64_t j = 0, n = 5; j < ARRAYSIZEOF(cqids_sorted); ++j,--n) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[n]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
fprintf(stderr, "Case 1: reverse scan set max version only\n");
|
|
{
|
|
htable_filter.set_max_versions(5);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
htable_filter.set_row_offset_per_column_family(0);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
query.set_scan_order(ObQueryFlag::Reverse);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9, 8, 7, 6, 5};
|
|
for (int64_t i = 0, m = 59; i < 10; ++i,--m) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", m);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0, n = 5; j < ARRAYSIZEOF(cqids_sorted); ++j, --n) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[n]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
fprintf(stderr, "Case 2: multiple result packet\n");
|
|
{
|
|
htable_filter.set_max_versions(1);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
htable_filter.set_row_offset_per_column_family(0);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
query.set_batch(3);
|
|
ObTableEntityIterator *iter = nullptr;
|
|
query.set_scan_order(ObQueryFlag::Reverse);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0, m = 59; i < 10; ++i, --m) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", m);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0, n = 5; j < ARRAYSIZEOF(cqids_sorted); ++j, --n) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[n]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
fprintf(stderr, "Case 3: Wildcard column tracker\n");
|
|
{
|
|
query.set_scan_order(ObQueryFlag::Reverse);
|
|
htable_filter.set_max_versions(5);
|
|
htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, 8);
|
|
htable_filter.set_row_offset_per_column_family(0); //in every row ,the first qualifier's five cells will be skipped
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
htable_filter.clear_columns();
|
|
query.set_batch(-1);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
int64_t timestamps[] = {7, 6, 5, 4, 3};
|
|
for (int64_t i = 0 , m = 59; i < 10; ++i, --m) {
|
|
// 10 rowkeys
|
|
//fprintf(stderr, "i=%ld\n", i);
|
|
sprintf(rows[i], "row%ld", m);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0 , n = 9; j < ARRAYSIZEOF(cqids_sorted); ++j, --n) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[n]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(TestBatchExecute, hcolumn_desc)
|
|
{
|
|
ObHColumnDescriptor column_desc;
|
|
ObString str = ObString::make_string("{\"Hbase\": {\"TimeToLive\": 3600}}");
|
|
ASSERT_EQ(OB_SUCCESS, column_desc.from_string(str));
|
|
fprintf(stderr, "ttl=%d\n", column_desc.get_time_to_live());
|
|
ASSERT_EQ(3600, column_desc.get_time_to_live());
|
|
}
|
|
|
|
|
|
TEST_F(TestBatchExecute, htable_ttl)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_ttl"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
char values[VERSIONS_COUNT][128];
|
|
for (int i = 0; i < VERSIONS_COUNT; ++i) {
|
|
sprintf(values[i], "ob%d", i);
|
|
}
|
|
const char* rowkey = "row0";
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j])); // cq0 ~ cq9
|
|
key3.set_int(INT64_MAX); // now
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string(values[j]));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
} // end for
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(1, result.count());
|
|
fprintf(stderr, "sleep 3\n");
|
|
sleep(3); // ttl is 5
|
|
{
|
|
// verify
|
|
ObTableQuery query;
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.set_valid(true);
|
|
htable_filter.clear_columns();
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
char expected_str[128];
|
|
ObString str;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
sprintf(expected_str, "ob%ld", j);
|
|
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_TRUE(0 == str.compare(ObString::make_string(expected_str)));
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// insert new value for cq0, cq2, cq4, ... cq8
|
|
entity_factory.free_and_reuse();
|
|
batch_operation.reset();
|
|
for (int64_t j = 0; j < COLUMNS_SIZE/2; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j*2]));
|
|
key3.set_int(INT64_MAX);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string(values[j*2]));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
} // end for
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(1, result.count());
|
|
|
|
// sleep for 3 seconds
|
|
fprintf(stderr, "sleep 3\n");
|
|
sleep(3); // ttl is 5
|
|
{
|
|
// verify
|
|
ObTableQuery query;
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.set_valid(true);
|
|
htable_filter.clear_columns();
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 2, 4, 6, 8};
|
|
char expected_str[128];
|
|
ObString str;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
sprintf(expected_str, "ob%ld", j*2);
|
|
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_TRUE(0 == str.compare(ObString::make_string(expected_str)));
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists secondary_index_test (
|
|
// C1 bigint primary key,
|
|
// C2 bigint,
|
|
// C3 varchar(100),
|
|
// index i1(c2) local,
|
|
// index i2(c3) local,
|
|
// index i3(c2, c3) local);
|
|
TEST_F(TestBatchExecute, secondary_index)
|
|
{
|
|
OB_LOG(INFO, "begin secondary_index");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("secondary_index_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
|
|
//
|
|
// > select * from secondary_index_test limit 10;
|
|
// +----+------+------+
|
|
// | C1 | C2 | C3 |
|
|
// +----+------+------+
|
|
// | 0 | 0 | aaa |
|
|
// | 2 | 1 | xxx |
|
|
// | 4 | 2 | yyy |
|
|
// | 6 | 3 | zzz |
|
|
// | 8 | 0 | AAA |
|
|
// | 10 | 1 | XXX |
|
|
// | 12 | 2 | YYY |
|
|
// | 14 | 3 | ZZZ |
|
|
// | 16 | 0 | aaa |
|
|
// | 18 | 1 | xxx |
|
|
// +----+------+------+
|
|
|
|
const char *c3_values[] = {"aaa", "xxx", "yyy", "zzz", "AAA", "XXX", "YYY", "ZZZ"};
|
|
const int64_t c3_values_count = ARRAYSIZEOF(c3_values);
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(i%4);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(ObString::make_string(c3_values[i%c3_values_count]));
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// query using index i1(c2)
|
|
{
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
// 扫描C2为1和2的所有数据
|
|
ObObj pk_objs_start[1];
|
|
pk_objs_start[0].set_int(1);
|
|
ObObj pk_objs_end[1];
|
|
pk_objs_end[0].set_int(2);
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 1);
|
|
range.end_key_.assign(pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("i1"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObObj obj1, obj2, obj3;
|
|
ObString str;
|
|
for (int64_t i = 0; i < BATCH_SIZE/2; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(3, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, obj1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, obj2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, obj3));
|
|
//fprintf(stderr, "%ld: (%s,%s,%s)\n", i, S(obj1), S(obj2), S(obj3));
|
|
ASSERT_EQ(OB_SUCCESS, obj3.get_varchar(str));
|
|
if (i % 2 == 0) {
|
|
ASSERT_EQ(1 , obj2.get_int());
|
|
ASSERT_EQ(2 + 4 * i, obj1.get_int()); // 2, 10, 18,...
|
|
} else {
|
|
ASSERT_EQ(2 , obj2.get_int());
|
|
ASSERT_EQ(4 + (i - 1) * 4, obj1.get_int()); // 4, 12, 20,...
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// query using index i2(c3)
|
|
{
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[1];
|
|
pk_objs_start[0].set_varchar(ObString::make_string("xxx"));
|
|
pk_objs_start[0].set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ObObj pk_objs_end[1];
|
|
pk_objs_end[0].set_varchar(ObString::make_string("xxx"));
|
|
pk_objs_end[0].set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 1);
|
|
range.end_key_.assign(pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("i2"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObObj obj1, obj2, obj3;
|
|
ObString str;
|
|
for (int64_t i = 0; i < BATCH_SIZE/4; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(3, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, obj1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, obj2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, obj3));
|
|
//fprintf(stderr, "%ld: (%s,%s,%s)\n", i, S(obj1), S(obj2), S(obj3));
|
|
ASSERT_EQ(OB_SUCCESS, obj3.get_varchar(str));
|
|
ASSERT_EQ(2+i*8, obj1.get_int());
|
|
ASSERT_EQ(1 , obj2.get_int());
|
|
ASSERT_TRUE(str == ObString::make_string(c3_values[(i%2==0)?1:5]));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// query using index i3(c2,c3)
|
|
{
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(1);
|
|
pk_objs_start[1].set_varchar(ObString::make_string("xxx"));
|
|
pk_objs_start[1].set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_int(1);
|
|
pk_objs_end[1].set_varchar(ObString::make_string("xxx"));
|
|
pk_objs_end[1].set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("i3"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObObj obj1, obj2, obj3;
|
|
ObString str;
|
|
for (int64_t i = 0; i < BATCH_SIZE/4; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(3, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, obj1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, obj2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, obj3));
|
|
//fprintf(stderr, "%ld: (%s,%s,%s)\n", i, S(obj1), S(obj2), S(obj3));
|
|
ASSERT_EQ(OB_SUCCESS, obj3.get_varchar(str));
|
|
ASSERT_EQ(2+i*8, obj1.get_int());
|
|
ASSERT_EQ(1 , obj2.get_int());
|
|
ASSERT_TRUE(str == ObString::make_string(c3_values[(i%2==0)?1:5]));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// 删除后一半row
|
|
batch_operation.reset();
|
|
result.reset();
|
|
for (int64_t i = 0; i < BATCH_SIZE/2; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int((BATCH_SIZE/2+i)*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE/2, result.count());
|
|
// then update C2 (2->0)
|
|
batch_operation.reset();
|
|
result.reset();
|
|
for (int64_t i = 0; i < BATCH_SIZE/2; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
if (i % 4 == 2) {
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.update(*entity));
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE/8, result.count());
|
|
// query using index i1(c2) again
|
|
{
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[1];
|
|
pk_objs_start[0].set_int(1);
|
|
ObObj pk_objs_end[1];
|
|
pk_objs_end[0].set_int(2);
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 1);
|
|
range.end_key_.assign(pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("i1"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObObj obj1, obj2, obj3;
|
|
ObString str;
|
|
for (int64_t i = 0; i < 13; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(3, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, obj1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, obj2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, obj3));
|
|
//fprintf(stderr, "%ld: (%s,%s,%s)\n", i, S(obj1), S(obj2), S(obj3));
|
|
ASSERT_EQ(OB_SUCCESS, obj3.get_varchar(str));
|
|
ASSERT_EQ(2+i*8, obj1.get_int());
|
|
ASSERT_EQ(1 , obj2.get_int());
|
|
ASSERT_TRUE(str == ObString::make_string(c3_values[(i%2==0)?1:5]));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
|
|
TEST_F(TestBatchExecute, htable_empty_qualifier)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_empty_cq"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
key2.set_varbinary(ObString::make_string("")); // empty qualifier
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("value_string"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*VERSIONS_COUNT, result.count());
|
|
////////////////////////////////////////////////////////////////
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
ObObj pk_objs_start[3];
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
ObObj pk_objs_end[3];
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row59"));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string("")));
|
|
htable_filter.set_max_versions(2);
|
|
htable_filter.set_valid(true);
|
|
{
|
|
// verify put result
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int64_t timestamps[] = {9, 8};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
key2.set_varbinary(ObString::make_string(""));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
{
|
|
// delete row50 by qualifier and version
|
|
const char* rowkey = "row50";
|
|
const char* cq = "";
|
|
int64_t ts = 8;
|
|
batch_operation.reset();
|
|
sprintf(rows[0], "%s", rowkey);
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
key2.set_varbinary(ObString::make_string(cq));
|
|
key3.set_int(ts); // delete the specified version
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
}
|
|
|
|
{
|
|
// verify delete result
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int64_t timestamps[] = {9, 8};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
key2.set_varbinary(ObString::make_string(""));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
if (0 == i && k == 1) {
|
|
key3.set_int(7);
|
|
} else {
|
|
key3.set_int(timestamps[k]);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
#define T_CASE_SUCC(SRC_TYPE, SRC_VAL, DELTA_TYPE, DELTA_VAL, RES_TYPE, RES_TYPE2, RES_VAL) \
|
|
src.set_##SRC_TYPE(SRC_VAL);\
|
|
delta.set_##DELTA_TYPE(DELTA_VAL);\
|
|
target_type.set_type(src.get_type()); \
|
|
target.set_null();\
|
|
ASSERT_EQ(OB_SUCCESS, ObTableService::obj_increment(delta, src, target_type, target)); \
|
|
ASSERT_EQ(Ob##RES_TYPE##Type, target.get_type()); \
|
|
ASSERT_EQ(RES_VAL, target.get_##RES_TYPE2());\
|
|
fprintf(stderr, "CASE: " #SRC_TYPE "(" #SRC_VAL ") + " #DELTA_TYPE "(" #DELTA_VAL ") = " #RES_TYPE2 "(" #RES_VAL ")\n");
|
|
|
|
#define T_CASE_FAIL(SRC_TYPE, SRC_VAL, DELTA_TYPE, DELTA_VAL, RES) \
|
|
src.set_##SRC_TYPE(SRC_VAL);\
|
|
delta.set_##DELTA_TYPE(DELTA_VAL);\
|
|
target_type.set_type(src.get_type()); \
|
|
target.set_null();\
|
|
ASSERT_EQ(RES, ObTableService::obj_increment(delta, src, target_type, target)); \
|
|
ASSERT_TRUE(target.is_null());\
|
|
fprintf(stderr, "CASE: " #SRC_TYPE "(" #SRC_VAL ") + " #DELTA_TYPE "(" #DELTA_VAL ") = " #RES "\n");
|
|
|
|
|
|
#define T_CASE_APP(SRC_VAL, SRC_CS_TYPE, DELTA_VAL, DELTA_CS_TYPE, RES_VAL, RES_CS_TYPE)\
|
|
src.set_varchar(ObString::make_string(SRC_VAL));\
|
|
src.set_collation_type(SRC_CS_TYPE);\
|
|
delta.set_varchar(ObString::make_string(DELTA_VAL));\
|
|
delta.set_collation_type(DELTA_CS_TYPE);\
|
|
target_type.set_type(ObVarcharType);\
|
|
target_type.set_collation_type(src.get_collation_type()); \
|
|
target.set_null();\
|
|
alloc.reset(); \
|
|
ASSERT_EQ(OB_SUCCESS, ObTableService::obj_append(delta, src, target_type, alloc, target)); \
|
|
ASSERT_EQ(ObVarcharType, target.get_type());\
|
|
ASSERT_EQ(RES_CS_TYPE, target.get_collation_type());\
|
|
ASSERT_TRUE(ObString::make_string(RES_VAL) == target.get_varchar());\
|
|
fprintf(stderr, "CASE: " #SRC_CS_TYPE "(" #SRC_VAL ") || " #DELTA_CS_TYPE "(" #DELTA_VAL ") = " #RES_VAL "\n");
|
|
|
|
TEST(TestQueryResult, alloc_memory_if_need)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t alloc_size = 1024;
|
|
ObTableQueryResult query_result;
|
|
int64_t total_size = query_result.allocator_.total();
|
|
while (OB_SUCC(ret)) {
|
|
ret = query_result.alloc_buf_if_need(alloc_size);
|
|
query_result.buf_.get_position() += alloc_size;
|
|
if (query_result.allocator_.total() != total_size) {
|
|
total_size = query_result.allocator_.total();
|
|
printf("allocator: %ld, result_buf: %ld\n", query_result.allocator_.total(), query_result.buf_.get_capacity());
|
|
}
|
|
}
|
|
ASSERT_EQ(query_result.buf_.get_capacity(), ObTableQueryResult::get_max_buf_block_size() * 1);
|
|
ASSERT_GT(query_result.allocator_.total(), ObTableQueryResult::get_max_buf_block_size() * 1);
|
|
ASSERT_LE(query_result.allocator_.total(), ObTableQueryResult::get_max_buf_block_size() * 3);
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, update_table_with_index_by_lowercase_rowkey)
|
|
{
|
|
|
|
OB_LOG(INFO, "begin update_table_with_index_by_lowercase_rowkey");
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("varchar_rowkey_update_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
// case for insert operation
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *insert_entity = NULL;
|
|
ObITableEntity *update_entity = NULL;
|
|
ObTableOperationResult r;
|
|
{
|
|
// case: insert with rowkey
|
|
insert_entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != insert_entity);
|
|
|
|
const char * rk_value = "TEST";
|
|
int64_t v_value = 139107;
|
|
ObObj rk_obj;
|
|
rk_obj.set_varchar(rk_value);
|
|
rk_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ObObj v_obj;
|
|
v_obj.set_int(v_value);
|
|
ASSERT_EQ(OB_SUCCESS, insert_entity->add_rowkey_value(rk_obj));
|
|
ASSERT_EQ(OB_SUCCESS, insert_entity->set_property(T, v_obj));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*insert_entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
}
|
|
|
|
{
|
|
// case: update with lowercase rowkey
|
|
update_entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != update_entity);
|
|
|
|
const char * rk_value = "test";
|
|
int64_t v_value = 1;
|
|
ObObj rk_obj;
|
|
rk_obj.set_varchar(rk_value);
|
|
rk_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ObObj v_obj;
|
|
v_obj.set_int(v_value);
|
|
ASSERT_EQ(OB_SUCCESS, update_entity->add_rowkey_value(rk_obj));
|
|
ASSERT_EQ(OB_SUCCESS, update_entity->set_property(T, v_obj));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*update_entity);
|
|
ASSERT_EQ(OB_ERR_UPDATE_ROWKEY_COLUMN, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
}
|
|
{
|
|
// query with index
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ObNewRange range;
|
|
range.set_whole_range();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("idx_T"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObObj obj1, obj2, obj3;
|
|
ObString str;
|
|
for (int64_t i = 0; i < 1; ++i)
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, obj1));
|
|
ASSERT_EQ(OB_SUCCESS, obj1.get_varchar(str));
|
|
ASSERT_TRUE(str == ObString::make_string("TEST"));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// todo@wenqu: mysqlproxy使用时报-1044,后面再调通。
|
|
// ObISQLClient::ReadResult res;
|
|
// uint64_t tenant_id = service_client_->get_tenant_id();
|
|
// ObString col_val;
|
|
// ret = service_client_->get_user_sql_client().read(res, tenant_id,
|
|
// "select /*+ index(varchar_rowkey_update_test idx_T)*/ K from test.varchar_rowkey_update_test");
|
|
// ASSERT_EQ(OB_SUCCESS, ret) << "tenant_id: " << tenant_id << "\n";
|
|
// sqlclient::ObMySQLResult *mysql_result = res.get_result();
|
|
// ASSERT_TRUE(NULL != mysql_result);
|
|
// ASSERT_EQ(OB_SUCCESS, mysql_result->next());
|
|
// ASSERT_EQ(OB_SUCCESS, mysql_result->get_varchar("K", col_val));
|
|
// ASSERT_TRUE(col_val == ObString::make_string("TEST"));
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists single_get_test
|
|
// (C1 bigint primary key,
|
|
// C2 double,
|
|
// C3 varchar(100) default 'hello world')
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_get)
|
|
{
|
|
OB_LOG(INFO, "begin single_get");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_get_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1234, 56.78, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1234;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 56.78;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get existed rowkey
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(3, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, value));
|
|
ASSERT_EQ(key, value);
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(c2_value, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
|
|
// rowkey existed, but column not exist
|
|
ObString C4 = ObString::make_string("C4");
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_NE(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get not existed rowkey
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, multi_get)
|
|
{
|
|
OB_LOG(INFO, "begin multi_get complex");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_get_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
// prepare data
|
|
ObITableEntity *entity = NULL;
|
|
ObString c3_value = "c3_value";
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
const ObITableEntity *result_entity = NULL;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// case 1:complex batch get and verify --- ObTableProccessType::TABLE_API_BATCH_RETRIVE
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
if (i % 2 == 1) {
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(!batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ObString str;
|
|
if (i % 2 == 1) {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(OB_SUCCESS != result_entity->get_property(C3, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
} else {
|
|
ASSERT_TRUE(OB_SUCCESS != result_entity->get_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
// case 2: multi_get --- ObTableProccessType::TABLE_API_MULTI_GET;
|
|
{
|
|
ObObj null_obj;
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = BATCH_SIZE-1; i >= 0; --i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_retrieve_property(C2));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
if (i % 2 == 1) {
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+(BATCH_SIZE-1-i)/2, value.get_int());
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
}
|
|
service_client_->free_table(the_table);
|
|
}
|
|
|
|
// create table if not exists single_insert_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100)) PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_insert)
|
|
{
|
|
OB_LOG(INFO, "begin single_insert");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_insert_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1234, 56.78, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1234;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 56.78;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1234
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(c2_value, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
|
|
// insert (C1, C3): (1235, "table api is delicious")
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1235
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
|
|
// insert (C1): (1236)
|
|
entity->reset();
|
|
key.set_int(key_key + 2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1236
|
|
entity->reset();
|
|
key.set_int(key_key + 2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == default_c3_value);
|
|
}
|
|
|
|
// create table if not exists single_insert_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100),
|
|
// C3_PREFIX varchar(10) GENERATED ALWAYS AS (substr(C3,1,2)))
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, insert_generate)
|
|
{
|
|
OB_LOG(INFO, "begin insert_generate_test");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("insert_generate_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1234, 56.78, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1234;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 56.78;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1234
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(c2_value, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
|
|
// insert (C1, C3): (1235, "table api is delicious")
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1235
|
|
entity->reset();
|
|
key.set_int(key_key + 1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
|
|
// insert (C1): (1236)
|
|
entity->reset();
|
|
key.set_int(key_key + 2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// get C1 == 1236
|
|
entity->reset();
|
|
key.set_int(key_key + 2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == default_c3_value);
|
|
}
|
|
|
|
// create table if not exists single_update_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100) default 'hello world')
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_update)
|
|
{
|
|
OB_LOG(INFO, "begin single_update");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_update_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1234, 56.78, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1234;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 56.78;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// update C2
|
|
{
|
|
entity->reset();
|
|
result_entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_double(78.9);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(78.9, value.get_double());
|
|
}
|
|
|
|
// test for cache: update C2
|
|
{
|
|
entity->reset();
|
|
result_entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_double(96.0);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(96.0, value.get_double());
|
|
}
|
|
}
|
|
|
|
// create table if not exists update_generate_test
|
|
// (C1 bigint primary key, C2 varchar(100), C3 varchar(100), GEN varchar(100) GENERATED ALWAYS AS (concat(C2,c3)) stored)
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, update_generate)
|
|
{
|
|
OB_LOG(INFO, "begin update_generate_test");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("update_generate_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1, 'hello ', "table api")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObString c2_value = ObString::make_string("hello ");
|
|
value.set_varchar(c2_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// update C2
|
|
{
|
|
entity->reset();
|
|
result_entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObString c2_update_value = ObString::make_string("hi ");
|
|
value.set_varchar(c2_update_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c2_value = ObString::make_string("hi ");
|
|
ASSERT_TRUE(str == c2_value);
|
|
}
|
|
}
|
|
|
|
// create table if not exists single_delete_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100)) PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_delete)
|
|
{
|
|
OB_LOG(INFO, "begin single_delete");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_delete_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// insert (C1, C2, C3): (1, 56.78, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1;
|
|
key.set_int(key_key);
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 56.78;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// delete
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// delete not exist row
|
|
{
|
|
entity->reset();
|
|
ObObj not_exist_key;
|
|
not_exist_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(not_exist_key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
|
|
// create table if not exists single_replace_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100) default 'hello world') PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_replace)
|
|
{
|
|
OB_LOG(INFO, "begin single_replace");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_replace_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableOperationResult r;
|
|
ObITableEntity *result_entity = NULL;
|
|
|
|
// insert (C1, C2, C3): (1, 1.1, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1;
|
|
key.set_int(key_key);
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 1.1;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// replace C3 (Duplicate rowkey)
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 2.2;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("obkv is delicious");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows()); // delete + insert
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("obkv is delicious");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
|
|
// replace C3 (new rowkey)
|
|
{
|
|
entity->reset();
|
|
ObObj new_key;
|
|
new_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(new_key));
|
|
double c2_value = 3.3;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("obkv and tableapi are delicious");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows()); // insert
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ObObj new_key;
|
|
new_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(new_key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("obkv and tableapi are delicious");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
|
|
// create table if not exists replace_unique_key_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100) default 'hello world',
|
|
// unique index i1(c2) local) PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, replace_unique_key)
|
|
{
|
|
OB_LOG(INFO, "begin replace_unique_key_test");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("replace_unique_key_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableOperationResult r;
|
|
ObITableEntity *result_entity = NULL;
|
|
|
|
// insert (C1, C2, C3): (1, 1.1, "table api is delicious")
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1;
|
|
key.set_int(key_key);
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 1.1;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("table api is delicious");
|
|
const ObString default_c3_value = ObString::make_string("hello world");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// replace C3 (Duplicate unique key)
|
|
{
|
|
entity->reset();
|
|
ObObj new_key;
|
|
new_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(new_key));
|
|
double c2_value = 1.1;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObString c3_value = ObString::make_string("ob is delicious");
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::replace(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows()); // delete + insert
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ObObj new_key;
|
|
new_key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(new_key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("ob is delicious");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
|
|
// create table if not exists single_insert_up_test
|
|
// (C1 bigint primary key,
|
|
// C2 double,
|
|
// C3 varchar(100) default 'hello world',
|
|
// UNIQUE KEY idx_c2 (C2)) PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, single_insert_up)
|
|
{
|
|
OB_LOG(INFO, "begin single_insert_up");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_insert_up_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableOperationResult r;
|
|
ObITableEntity *result_entity = NULL;
|
|
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
ObObj value;
|
|
int key_key = 1;
|
|
key.set_int(key_key);
|
|
|
|
// insert_or_update C2: insert
|
|
// [1], [1.1], ['hello world']
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 1.1;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(1.1, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
|
|
// insert_or_update C2: insert
|
|
// [2], [2.2], ['hello world']
|
|
{
|
|
ObObj key;
|
|
int key_key = 2;
|
|
key.set_int(key_key);
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 2.2;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
ObObj key;
|
|
int key_key = 2;
|
|
key.set_int(key_key);
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(2.2, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
|
|
// current has 2 rows
|
|
// [1], [1.1], ['hello world']
|
|
// [2], [2.2], ['hello world']
|
|
|
|
|
|
// insert_or_update C2: update -----> rowkey conflict
|
|
// [1], [3.3], ['hello world']
|
|
{
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 3.3;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(3.3, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
|
|
// current has 2 rows
|
|
// [1], [3.3], ['hello world']
|
|
// [2], [2.2], ['hello world']
|
|
|
|
// insert_or_update C2: update again ----->unique key confilct
|
|
// [3], [3.3], ['hello world']
|
|
{
|
|
ObObj key;
|
|
int key_key = 3;
|
|
key.set_int(key_key);
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 3.3;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
ASSERT_EQ(OB_ERR_UPDATE_ROWKEY_COLUMN, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj key;
|
|
int key_key = 3;
|
|
key.set_int(key_key);
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(0, result_entity->get_properties_count());
|
|
}
|
|
|
|
// current has 2 rows
|
|
// [1], [3.3], ['hello world']
|
|
// [2], [2.2], ['hello world']
|
|
|
|
// insert_or_update C2: update again ----->rowkey & unique key confilct
|
|
// [3], [2.2], ['hello world']
|
|
{
|
|
ObObj key;
|
|
int key_key = 3;
|
|
key.set_int(key_key);
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
double c2_value = 2.2;
|
|
value.set_double(c2_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::insert_or_update(*entity);
|
|
// TODO:@linjing 和sql行为不一致
|
|
ASSERT_EQ(OB_ERR_UPDATE_ROWKEY_COLUMN, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// current has 2 rows
|
|
// [1], [3.3], ['hello world']
|
|
// [2], [2.2], ['hello world']
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(3.3, value.get_double());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
|
|
// CREATE TABLE IF NOT EXISTS `kv_query_test` (
|
|
// C1 bigint,
|
|
// C2 bigint,
|
|
// C3 bigint,
|
|
// PRIMARY KEY(`C1`, `C2`),
|
|
// KEY idx_c2 (`C2`),
|
|
// KEY idx_c3 (`C3`),
|
|
// KEY idx_c2c3(`C2`, `C3`));
|
|
// INSERT INTO kv_query_test VALUES (1,2,3),(4,5,6),(7,8,9),(10,11,12),(13,14,15);
|
|
TEST_F(TestBatchExecute, table_query_with_secondary_index)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("kv_query_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableOperationResult r;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableEntityIterator *iter = nullptr;
|
|
int expect_query_cnt = 5;
|
|
ObArray<ObObj> properties_values;
|
|
|
|
// insert
|
|
{
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const int INERT_COUNT = 5;
|
|
for (int64_t i = 0; i < INERT_COUNT; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key1;
|
|
key1.set_int(i * 3 + 1);
|
|
ObObj key2;
|
|
key2.set_int(i * 3 + 2);
|
|
ObObj value;
|
|
value.set_int(i * 3 + 3);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(INERT_COUNT, result.count());
|
|
for (int64_t i = 0; i < INERT_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
|
|
//scan
|
|
ObTableQuery query;
|
|
{
|
|
// case 1: primary key
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(++i, properties_values.at(0).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(1).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(2).get_int());
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
{
|
|
// case 2: index is the subset of primary key
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c2")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(++i, properties_values.at(0).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(1).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(2).get_int());
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
{
|
|
// case 3: has itersection between primary key and index
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c2c3")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(++i, properties_values.at(0).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(1).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(2).get_int());
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
{
|
|
// case 4: has no itersection between primary key and index
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c3")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(++i, properties_values.at(0).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(1).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(2).get_int());
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
{
|
|
// case 5: has no select column in query
|
|
query.reset();
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(++i, properties_values.at(0).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(1).get_int());
|
|
ASSERT_EQ(++i, properties_values.at(2).get_int());
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
// teardown
|
|
iter = nullptr;
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// CREATE TABLE IF NOT EXISTS `check_scan_range_test` (
|
|
// C1 bigint,
|
|
// C2 varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
|
|
// C3 bigint,
|
|
// PRIMARY KEY(`C1`, `C2`),
|
|
// KEY idx_c3 (`C3`));
|
|
// INSERT INTO kv_query_test VALUES (1,'hello',3),(4,'hello',6),(7,'hello',9),(10,'hello',12),(13,'hello',15);
|
|
TEST_F(TestBatchExecute, check_scan_range)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("check_scan_range_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableOperationResult r;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableEntityIterator *iter = nullptr;
|
|
int expect_query_cnt = 5;
|
|
ObArray<ObObj> properties_values;
|
|
|
|
// insert
|
|
{
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const int INERT_COUNT = 5;
|
|
for (int64_t i = 0; i < INERT_COUNT; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key1;
|
|
key1.set_int(i * 3 + 1);
|
|
ObObj key2;
|
|
key2.set_varchar("hello");
|
|
key2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ObObj value;
|
|
value.set_int(i * 3 + 3);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(INERT_COUNT, result.count());
|
|
for (int64_t i = 0; i < INERT_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
|
|
// case 1: scan by primary key, but key objs count is invalid
|
|
ObTableQuery query;
|
|
{
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[1];
|
|
pk_objs_start[0].set_int(0);
|
|
// pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[1];
|
|
pk_objs_end[0].set_max_value();
|
|
// pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 1);
|
|
range.end_key_.assign(pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_KV_SCAN_RANGE_MISSING, the_table->execute_query(query, iter)); // wrong rowkey size
|
|
}
|
|
|
|
// case 2: scan by primary key, but key objs type is invalid
|
|
{
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_double(3.14); // invalid type
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_KV_COLUMN_TYPE_NOT_MATCH, the_table->execute_query(query, iter)); // wrong rowkey type
|
|
}
|
|
|
|
// case 3: scan by primary key, but collation type is invalid
|
|
{
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_min_value();
|
|
pk_objs_start[1].set_varchar("hello");
|
|
pk_objs_start[1].set_collation_type(ObCollationType::CS_TYPE_GBK_BIN); // invalid collation type
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_KV_COLLATION_MISMATCH, the_table->execute_query(query, iter)); // wrong collation type
|
|
}
|
|
|
|
// case 4: scan by primary key, but accuracy is invalid
|
|
{
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_min_value();
|
|
pk_objs_start[1].set_varchar("hello11111111111"); // invalid accuracy, too long
|
|
pk_objs_start[1].set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN);
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, the_table->execute_query(query, iter)); // wrong accuracy
|
|
}
|
|
|
|
// case 5: scan by second index, but range is incomplete, lack rowkey.
|
|
// server will complement rowkey range.
|
|
{
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0); // lack rowkey
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c3")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
int64_t i = 1;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_properties_values(properties_values));
|
|
ASSERT_EQ(3, properties_values.count());
|
|
ASSERT_EQ(i, properties_values.at(0).get_int());
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, properties_values.at(1).get_varchar(str));
|
|
ASSERT_EQ(0, str.case_compare("hello"));
|
|
ASSERT_EQ(i + 2, properties_values.at(2).get_int());
|
|
i += 3;
|
|
properties_values.reset();
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, expect_query_cnt);
|
|
}
|
|
|
|
// teardown
|
|
iter = nullptr;
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, multi_insert)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_insert_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
OB_LOG(INFO, "begin multi_insert");
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
// multi insert
|
|
{
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
}
|
|
}
|
|
// insert again
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE + 1; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
// 冲突,但是非atomic,其他行可以写入
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, multi_delete)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_delete_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
OB_LOG(INFO, "begin multi_delete");
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
// prepare data
|
|
ObITableEntity *entity = NULL;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
// delete half of the rows
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
if (i % 2 == 0) {
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
} else {
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
}
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
if (i < BATCH_SIZE/2) {
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_scan_with_filter)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_filter"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
switch (i % 4) {
|
|
case 0: // row52
|
|
value.set_varbinary(ObString::make_string("xx_string1"));
|
|
break;
|
|
case 1: // row53
|
|
value.set_varbinary(ObString::make_string("aa_string1"));
|
|
break;
|
|
case 2: // row50
|
|
value.set_varbinary(ObString::make_string("xy_string2"));
|
|
break;
|
|
case 3: // row51
|
|
value.set_varbinary(ObString::make_string("ab_string2"));
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// htable filter cases
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
ObObj pk_objs_start[3];
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
ObObj pk_objs_end[3];
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row59"));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[6] = {0, 3, 1, 4, 7, 9};
|
|
for (int i = 0; OB_SUCCESS == ret && i < 6; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier[i])));
|
|
} // end for
|
|
htable_filter.set_max_versions(2);
|
|
htable_filter.set_time_range(3, 8);
|
|
htable_filter.set_row_offset_per_column_family(2);
|
|
htable_filter.set_max_results_per_column_family(8);
|
|
htable_filter.set_valid(true);
|
|
{
|
|
fprintf(stderr, "case: = binary comparator\n");
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', =, 'binary:xy_string2', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
// check
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 3; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i*4+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
v.set_varbinary(ObString::make_string("xy_string2"));
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case : > binary filter
|
|
fprintf(stderr, "case: > binary comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', >, 'binary:w', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+2*i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("xy_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("xx_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: < binary filter
|
|
fprintf(stderr, "case: < binary comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', <, 'binary:w', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*2+1);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: >= binary filter
|
|
fprintf(stderr, "case: >= binary comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', >=, 'binary:xx_string1', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*2);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("xy_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("xx_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: <= binary filter
|
|
fprintf(stderr, "case: <= binary comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', <=, 'binary:ab_string2', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*2+1);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: prefix filter
|
|
fprintf(stderr, "case: = prefix comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', =, 'binaryprefix:a', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*2+1);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: != prefix filter
|
|
fprintf(stderr, "case: != prefix comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', !=, 'binaryprefix:x', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*2+1);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: = substring filter
|
|
fprintf(stderr, "case: = substring comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', =, 'substring:string1', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 4; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i/2*4+2+(i%2));
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("xx_string1"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: != substring filter
|
|
fprintf(stderr, "case: != substring comparator\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("SingleColumnValueFilter('cf1', 'cq1', !=, 'substring:string1', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 6; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i/2*4+(i%2));
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("xy_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: ValueFilter
|
|
fprintf(stderr, "case: ValueFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("ValueFilter(=, 'binary:aa_string1')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 2; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i*4+3);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
v.set_varbinary(ObString::make_string("aa_string1"));
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: QualifierFilter
|
|
fprintf(stderr, "case: QualifierFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("QualifierFilter(>=, 'binary:cq1')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {3, 4, 7, 9};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case: RowFilter
|
|
fprintf(stderr, "case: RowFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("RowFilter(>=, 'binary:row55')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 5; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 55+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: SkipFilter
|
|
fprintf(stderr, "case: SkipFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("Skip QualifierFilter(>=, 'binary:cq1')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: WhileMatchFilter
|
|
fprintf(stderr, "case: WhileMatchFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("While SingleColumnValueFilter('cf1', 'cq1', !=, 'substring:string1', true, false)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 2; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i/2*4+(i%2));
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ObObj v;
|
|
if (i % 2 == 0) {
|
|
v.set_varbinary(ObString::make_string("xy_string2"));
|
|
} else {
|
|
v.set_varbinary(ObString::make_string("ab_string2"));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
ASSERT_EQ(val, v);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: FilterListAND
|
|
fprintf(stderr, "case: FilterListAND\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("RowFilter(>=, 'binary:row55') AND QualifierFilter(>=, 'binary:cq1') AND SKIP ValueFilter(!=, 'binary:ab_string2')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {3, 4, 7, 9};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 3; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 56+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: FilterListOR
|
|
fprintf(stderr, "case: FilterListOR\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("RowFilter(>=, 'binary:row55') OR ValueFilter(=, 'binary:ab_string2')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 6; ++i) {
|
|
// 10 rowkeys
|
|
if (i <=0) {
|
|
sprintf(rows[i], "row51");
|
|
} else {
|
|
sprintf(rows[i], "row%ld", 54+i);
|
|
}
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
// case: FilterListOR
|
|
fprintf(stderr, "case: FilterListOR 2\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("ValueFilter(=, 'binary:xx_string1') OR ValueFilter(=, 'binary:ab_string2') OR ValueFilter(=, 'binary:xy_string2')"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 10; ++i) {
|
|
if (i % 4 == 3) {
|
|
continue;
|
|
}
|
|
sprintf(rows[i], "row%ld", 50+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case : PageFilter
|
|
fprintf(stderr, "case: PageFilter\n");
|
|
// check
|
|
{
|
|
// page size is 3
|
|
htable_filter.set_filter(ObString::make_string("PageFilter(3)"));
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[4] = {1, 3, 4, 7};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 3; ++i) {
|
|
// only 3 rowkeys (equals to page size)
|
|
sprintf(rows[i], "row%ld", 50+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 4; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 2; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
// case : ColumnCountGetFilter
|
|
fprintf(stderr, "case: ColumnCountGetFilter\n");
|
|
// check
|
|
{
|
|
htable_filter.set_filter(ObString::make_string("ColumnCountGetFilter(3)"));
|
|
htable_filter.set_max_versions(1);
|
|
htable_filter.set_row_offset_per_column_family(0);
|
|
htable_filter.set_max_results_per_column_family(-1);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
htable_filter.set_max_versions(2);
|
|
htable_filter.set_row_offset_per_column_family(2);
|
|
htable_filter.set_max_results_per_column_family(8);
|
|
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[3] = {0, 1, 3};
|
|
int64_t timestamps[2] = {7, 6};
|
|
for (int64_t i = 0; i < 1; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", 50+i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < 3; ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < 1; ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, single_increment_append)
|
|
{
|
|
OB_LOG(INFO, "begin single_increment");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("single_increment_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
// insert C2
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 10;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 1000;
|
|
ObObj c2_obj;
|
|
c2_obj.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_obj));
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ObObj c3_obj;
|
|
c3_obj.set_varchar(c3_value);
|
|
c3_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_obj));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
// insert another row (11, 1000, null)
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
// insert another row (12, null, "hello world")
|
|
entity->reset();
|
|
key.set_int(key_key+2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_obj));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ObObj value;
|
|
// append C3
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::append(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, value));
|
|
ASSERT_EQ(key_key, value.get_int());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello worldhello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
ASSERT_EQ(CS_TYPE_UTF8MB4_GENERAL_CI, value.get_collation_type());
|
|
}
|
|
// increment C2
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(111);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::increment(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(false);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INCREMENT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value+111, value.get_int());
|
|
}
|
|
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value+111, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello worldhello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
}
|
|
// append to null column
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::append(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, value));
|
|
ASSERT_EQ(key_key+1, value.get_int());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
ASSERT_EQ(CS_TYPE_UTF8MB4_GENERAL_CI, value.get_collation_type());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key+1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(value_value, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
}
|
|
// increment null value
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key+2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(111);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::increment(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(false);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INCREMENT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(111, value.get_int());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key+2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(111, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
}
|
|
|
|
// increment row not exist
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key+3);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(111);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ObTableOperation table_operation = ObTableOperation::increment(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(false);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INCREMENT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(111, value.get_int());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key+3);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(111, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
}
|
|
// append to row not exist
|
|
{
|
|
entity->reset();
|
|
key.set_int(key_key+4);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ObTableOperation table_operation = ObTableOperation::append(*entity);
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, req_options, r));
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, value));
|
|
ASSERT_EQ(key_key+4, value.get_int());
|
|
ASSERT_EQ(1, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
ASSERT_EQ(CS_TYPE_UTF8MB4_GENERAL_CI, value.get_collation_type());
|
|
}
|
|
// get
|
|
{
|
|
ObObj null_obj;
|
|
entity->reset();
|
|
key.set_int(key_key+4);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ObTableOperation table_operation = ObTableOperation::retrieve(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(2, result_entity->get_properties_count());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ObString c3_new_value = ObString::make_string("hello world");
|
|
ASSERT_TRUE(str == c3_new_value);
|
|
}
|
|
service_client_->free_table(the_table);
|
|
}
|
|
|
|
// create table if not exists multi_update_test
|
|
// (C1 bigint primary key, C2 double, C3 varchar(100) default 'hello world')
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, multi_update)
|
|
{
|
|
OB_LOG(INFO, "begin multi_update");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_update_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
// multi insert
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(2*i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
}
|
|
}
|
|
|
|
ObString c3_value = "c3_value";
|
|
// update C3
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(2*i);
|
|
ObObj value;
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(2*i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
// update half of the rows
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value;
|
|
value.set_int(200+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
if (i % 2 == 0) {
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
} else {
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
}
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
if (i < BATCH_SIZE/2) {
|
|
ASSERT_EQ(200+i*2, value.get_int());
|
|
} else {
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, multi_insert_or_update)
|
|
{
|
|
OB_LOG(INFO, "begin multi_insert_or_update");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_insert_or_update_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
// multi insert
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value;
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// get and verify
|
|
const ObITableEntity *result_entity = NULL;
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(i, value.get_int());
|
|
}
|
|
}
|
|
|
|
// multi update
|
|
ObString c3_value = "c3_value";
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value1;
|
|
value1.set_int(i+1);
|
|
ObObj value2;
|
|
value2.set_varchar(c3_value);
|
|
value2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value2));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(i+1, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
// create table if not exists multi_replace_test
|
|
// (C1 bigint primary key, C2 bigint, C3 varchar(100) default 'hello world')
|
|
// PARTITION BY KEY(C1) PARTITIONS 16
|
|
TEST_F(TestBatchExecute, multi_replace)
|
|
{
|
|
OB_LOG(INFO, "begin multi_replace_test");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_replace_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const int64_t SIZE = 10;
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value;
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(i, value.get_int());
|
|
}
|
|
}
|
|
// replace again
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value;
|
|
value.set_int(200+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows()); // delete + insert
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(200+i, value.get_int());
|
|
}
|
|
}
|
|
// replace again (unique key C2 dup)
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(100+i);
|
|
ObObj value;
|
|
value.set_int(200+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows()); // delete + insert
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
// get and verify
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(SIZE, result.count());
|
|
for (int64_t i = 0; i < SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(200+i, value.get_int());
|
|
}
|
|
}
|
|
}
|
|
|
|
// unstable test cases
|
|
// TEST_F(TestBatchExecute, htable_delete)
|
|
// {
|
|
// // setup
|
|
// ObTable *the_table = NULL;
|
|
// int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_delete"), the_table);
|
|
// ASSERT_EQ(OB_SUCCESS, ret);
|
|
// the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
// ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
// ObTableBatchOperation batch_operation;
|
|
// ObITableEntity *entity = NULL;
|
|
// DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
// ASSERT_TRUE(NULL != rows);
|
|
// static constexpr int64_t VERSIONS_COUNT = 10;
|
|
// static constexpr int64_t COLUMNS_SIZE = 10;
|
|
// char qualifier[COLUMNS_SIZE][128];
|
|
// char qualifier2[COLUMNS_SIZE][128];
|
|
// for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
// {
|
|
// sprintf(qualifier[i], "cq%d", i);
|
|
// } // end for
|
|
// ObObj key1, key2, key3;
|
|
// ObObj value;
|
|
// for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
// sprintf(rows[i], "row%ld", i);
|
|
// key1.set_varbinary(ObString::make_string(rows[i]));
|
|
// for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
// key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
// for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
// {
|
|
// key3.set_int(k);
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// switch (i % 4) {
|
|
// case 0:
|
|
// value.set_varbinary(ObString::make_string("string2"));
|
|
// break;
|
|
// case 1:
|
|
// value.set_varbinary(ObString::make_string("string3"));
|
|
// break;
|
|
// case 2: // row50
|
|
// value.set_varbinary(ObString::make_string("string0"));
|
|
// break;
|
|
// case 3:
|
|
// value.set_varbinary(ObString::make_string("string1"));
|
|
// break;
|
|
// default:
|
|
// ASSERT_TRUE(0);
|
|
// }
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
// } // end for
|
|
// } // end for
|
|
// } // end for
|
|
|
|
// ASSERT_TRUE(!batch_operation.is_readonly());
|
|
// ASSERT_TRUE(batch_operation.is_same_type());
|
|
// ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
// OB_LOG(INFO, "batch execute result", K(result));
|
|
// ASSERT_EQ(BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT, result.count());
|
|
// for (int64_t i = 0; i < BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT; ++i)
|
|
// {
|
|
// const ObTableOperationResult &r = result.at(i);
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
// ASSERT_EQ(1, r.get_affected_rows());
|
|
// ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
// ASSERT_TRUE(result_entity->is_empty());
|
|
// } // end for
|
|
|
|
// ////////////////////////////////////////////////////////////////
|
|
// {
|
|
// fprintf(stderr, "case: delete by row\n");
|
|
// const char* rowkey = "row1";
|
|
// batch_operation.reset();
|
|
// sprintf(rows[0], "%s", rowkey);
|
|
// key1.set_varbinary(ObString::make_string(rows[0]));
|
|
// key2.set_null(); // delete all qualifier
|
|
// key3.set_int(-INT64_MAX); // delete all version
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
|
|
// // verify
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
// ObObj pk_objs_start[3];
|
|
// pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_start[1].set_min_value();
|
|
// pk_objs_start[2].set_min_value();
|
|
// ObObj pk_objs_end[3];
|
|
// pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_end[1].set_max_value();
|
|
// pk_objs_end[2].set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(pk_objs_start, 3);
|
|
// range.end_key_.assign(pk_objs_end, 3);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// ObHTableFilter &htable_filter = query.htable_filter();
|
|
// htable_filter.set_valid(true);
|
|
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
// }
|
|
// {
|
|
// fprintf(stderr, "case: delete by qualifier: cq3, cq5\n");
|
|
// const char* rowkey = "row2";
|
|
// batch_operation.reset();
|
|
// sprintf(rows[0], "%s", rowkey);
|
|
// key1.set_varbinary(ObString::make_string(rows[0]));
|
|
// int cqids[] = {3, 5};
|
|
// for (int64_t j = 0; j < ARRAYSIZEOF(cqids); ++j) {
|
|
// sprintf(qualifier2[j], "cq%d", cqids[j]);
|
|
// key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
// key3.set_int(-INT64_MAX); // delete all version
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
// }
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
|
|
// // verify
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
// ObObj pk_objs_start[3];
|
|
// pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_start[1].set_min_value();
|
|
// pk_objs_start[2].set_min_value();
|
|
// ObObj pk_objs_end[3];
|
|
// pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_end[1].set_max_value();
|
|
// pk_objs_end[2].set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(pk_objs_start, 3);
|
|
// range.end_key_.assign(pk_objs_end, 3);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// ObHTableFilter &htable_filter = query.htable_filter();
|
|
// htable_filter.set_valid(true);
|
|
// htable_filter.clear_columns();
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// int cqids_sorted[] = {0, 1, 2, 4, 6, 7, 8, 9};
|
|
// int64_t timestamps[] = {9};
|
|
// for (int64_t i = 0; i < 1; ++i) {
|
|
// key1.set_varbinary(ObString::make_string(rowkey));
|
|
// for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// // 4 qualifier
|
|
// sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
// key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
// for (int64_t k = 0; k < 1; ++k)
|
|
// {
|
|
// key3.set_int(timestamps[k]);
|
|
// ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
// ObObj rk, cq, ts, val;
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// //fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
// ASSERT_EQ(key1, rk);
|
|
// ASSERT_EQ(key2, cq);
|
|
// ASSERT_EQ(key3, ts);
|
|
// } // end for
|
|
// }
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
// }
|
|
// {
|
|
// fprintf(stderr, "case: delete by qualifier & version: cq3 & version5\n");
|
|
// const char* rowkey = "row3";
|
|
// const char* cq = "cq3";
|
|
// int64_t ts = 5;
|
|
// batch_operation.reset();
|
|
// sprintf(rows[0], "%s", rowkey);
|
|
// key1.set_varbinary(ObString::make_string(rows[0]));
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// key3.set_int(ts); // delete the specified version
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
|
|
// // verify
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
// ObObj pk_objs_start[3];
|
|
// pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_start[1].set_min_value();
|
|
// pk_objs_start[2].set_min_value();
|
|
// ObObj pk_objs_end[3];
|
|
// pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_end[1].set_max_value();
|
|
// pk_objs_end[2].set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(pk_objs_start, 3);
|
|
// range.end_key_.assign(pk_objs_end, 3);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// ObHTableFilter &htable_filter = query.htable_filter();
|
|
// htable_filter.set_valid(true);
|
|
// htable_filter.clear_columns();
|
|
// ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(cq)));
|
|
// htable_filter.set_max_versions(INT32_MAX);
|
|
// htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// int64_t timestamps[] = {9, 8, 7, 6, 4, 3, 2, 1, 0};
|
|
// for (int64_t i = 0; i < 1; ++i) {
|
|
// key1.set_varbinary(ObString::make_string(rowkey));
|
|
// for (int64_t j = 0; j < 1; ++j) {
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
// {
|
|
// key3.set_int(timestamps[k]);
|
|
// ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
// ObObj rk, cq, ts, val;
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// //fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
// ASSERT_EQ(key1, rk);
|
|
// ASSERT_EQ(key2, cq);
|
|
// ASSERT_EQ(key3, ts);
|
|
// } // end for
|
|
// }
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
// }
|
|
// {
|
|
// fprintf(stderr, "case: delete by qualifier & version: cq3 & INT64_MAX\n");
|
|
// const char* rowkey = "row4";
|
|
// const char* cq = "cq3";
|
|
// batch_operation.reset();
|
|
// sprintf(rows[0], "%s", rowkey);
|
|
// key1.set_varbinary(ObString::make_string(rows[0]));
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// key3.set_int(INT64_MAX); // delete the latest version
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
|
|
// // verify
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
// ObObj pk_objs_start[3];
|
|
// pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_start[1].set_min_value();
|
|
// pk_objs_start[2].set_min_value();
|
|
// ObObj pk_objs_end[3];
|
|
// pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_end[1].set_max_value();
|
|
// pk_objs_end[2].set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(pk_objs_start, 3);
|
|
// range.end_key_.assign(pk_objs_end, 3);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// ObHTableFilter &htable_filter = query.htable_filter();
|
|
// htable_filter.set_valid(true);
|
|
// htable_filter.clear_columns();
|
|
// ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(cq)));
|
|
// htable_filter.set_max_versions(INT32_MAX);
|
|
// htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// int64_t timestamps[] = {8, 7, 6, 5, 4, 3, 2, 1, 0};
|
|
// for (int64_t i = 0; i < 1; ++i) {
|
|
// key1.set_varbinary(ObString::make_string(rowkey));
|
|
// for (int64_t j = 0; j < 1; ++j) {
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
// {
|
|
// key3.set_int(timestamps[k]);
|
|
// ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
// ObObj rk, cq, ts, val;
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// //fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
// ASSERT_EQ(key1, rk);
|
|
// ASSERT_EQ(key2, cq);
|
|
// ASSERT_EQ(key3, ts);
|
|
// } // end for
|
|
// }
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
|
|
// }
|
|
// {
|
|
// fprintf(stderr, "case: delete by qualifier & version: cq3 & version<=5\n");
|
|
// const char* rowkey = "row5";
|
|
// const char* cq = "cq3";
|
|
// int64_t ts = 5;
|
|
// batch_operation.reset();
|
|
// sprintf(rows[0], "%s", rowkey);
|
|
// key1.set_varbinary(ObString::make_string(rows[0]));
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// key3.set_int(-ts); // delete the versions < 5
|
|
// entity = entity_factory.alloc();
|
|
// ASSERT_TRUE(NULL != entity);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
// ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
|
|
// ObTableBatchOperationResult result;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
|
|
// // verify
|
|
// ObTableQuery query;
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
// ObObj pk_objs_start[3];
|
|
// pk_objs_start[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_start[1].set_min_value();
|
|
// pk_objs_start[2].set_min_value();
|
|
// ObObj pk_objs_end[3];
|
|
// pk_objs_end[0].set_varbinary(ObString::make_string(rowkey));
|
|
// pk_objs_end[1].set_max_value();
|
|
// pk_objs_end[2].set_max_value();
|
|
// ObNewRange range;
|
|
// range.start_key_.assign(pk_objs_start, 3);
|
|
// range.end_key_.assign(pk_objs_end, 3);
|
|
// range.border_flag_.set_inclusive_start();
|
|
// range.border_flag_.set_inclusive_end();
|
|
// ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
// ObHTableFilter &htable_filter = query.htable_filter();
|
|
// htable_filter.set_valid(true);
|
|
// ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(cq)));
|
|
// htable_filter.set_max_versions(INT32_MAX);
|
|
// htable_filter.set_time_range(ObHTableConstants::INITIAL_MIN_STAMP, ObHTableConstants::INITIAL_MAX_STAMP);
|
|
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// int64_t timestamps[] = {9, 8, 7, 6};
|
|
// for (int64_t i = 0; i < 1; ++i) {
|
|
// key1.set_varbinary(ObString::make_string(rowkey));
|
|
// for (int64_t j = 0; j < 1; ++j) {
|
|
// key2.set_varbinary(ObString::make_string(cq));
|
|
// for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
// {
|
|
// key3.set_int(timestamps[k]);
|
|
// ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
// ObObj rk, cq, ts, val;
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// //fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
// ASSERT_EQ(key1, rk);
|
|
// ASSERT_EQ(key2, cq);
|
|
// ASSERT_EQ(key3, ts);
|
|
// } // end for
|
|
// }
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
// }
|
|
// //////////////////////////////////////////////////////////////
|
|
// teardown
|
|
// service_client_->free_table(the_table);
|
|
// the_table = NULL;
|
|
// delete [] rows;
|
|
// }
|
|
|
|
TEST_F(TestBatchExecute, complex_batch_execute)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("complex_batch_execute_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
OB_LOG(INFO, "begin complex_batch_execute");
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
// prepare data
|
|
ObITableEntity *entity = NULL;
|
|
ObString c3_value = "c3_value";
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
|
|
{
|
|
// complex batch execute with hybrid operations types
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
switch (i % 6) {
|
|
case 0: // get
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
break;
|
|
case 1: // insert
|
|
value.set_int(200+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
break;
|
|
case 2: // delete
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
break;
|
|
case 3: // update
|
|
value.set_int(300+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.update(*entity));
|
|
break;
|
|
case 4: // insert_or_update
|
|
value.set_int(400+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
break;
|
|
case 5: // replace
|
|
value.set_int(500+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.replace(*entity));
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
break;
|
|
}
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(!batch_operation.is_same_type());
|
|
ASSERT_TRUE(!batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObString str;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
switch (i % 6) {
|
|
case 0: // get
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
break;
|
|
case 1: // insert
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, r.get_errno());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
case 2: // delete
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::DEL, r.type());
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
case 3: // update
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
case 4: // insert_or_update
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
case 5: // replace
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(2, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::REPLACE, r.type());
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
// get and verify
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_retrieve_property(C2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_retrieve_property(C3));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_TRUE(batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
ObObj value;
|
|
ObString str;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
//fprintf(stderr, "result %ld\n", i);
|
|
switch (i % 6) {
|
|
case 0: // get
|
|
case 1: // insert
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(100+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
break;
|
|
case 2: // delete
|
|
// entry not exist
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
break;
|
|
case 3: // update
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(300+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
break;
|
|
case 4: // insert_or_update
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(400+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
// verify the semantic of PUT
|
|
//
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == c3_value);
|
|
break;
|
|
case 5: // replace
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ASSERT_EQ(500+i, value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
service_client_->free_table(the_table);
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, increment_and_append_batch)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("multi_increment_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
// prepare
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
ObString c3_new_value = ObString::make_string("hello worldhello world");
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
// case
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObObj value;
|
|
if (0 == i % 2) {
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.increment(*entity));
|
|
} else if (1 == i % 2) {
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.append(*entity));
|
|
}
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(!batch_operation.is_same_type());
|
|
ASSERT_TRUE(!batch_operation.is_same_properties_names());
|
|
ObTableRequestOptions req_options;
|
|
req_options.set_returning_affected_entity(true);
|
|
req_options.set_returning_rowkey(true);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, req_options, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
if (0 == i % 2) {
|
|
ASSERT_EQ(ObTableOperationType::INCREMENT, r.type());
|
|
} else {
|
|
ASSERT_EQ(ObTableOperationType::APPEND, r.type());
|
|
}
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(!result_entity->is_empty());
|
|
ObObj value;
|
|
ASSERT_EQ(1, result_entity->get_rowkey_size());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_rowkey_value(0, value));
|
|
ASSERT_EQ(i*2, value.get_int());
|
|
|
|
ObObj c2_obj, c3_obj;
|
|
ObObj val2, val3;
|
|
if (0 == i % 2) {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SEARCH_NOT_FOUND, result_entity->get_property(C3, c3_obj));
|
|
val2.set_int(100+2*i);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
} else {
|
|
ASSERT_EQ(OB_SEARCH_NOT_FOUND, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, c3_obj));
|
|
val3.set_varchar(c3_new_value);
|
|
val3.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
}
|
|
} // end for
|
|
|
|
|
|
// get and verify
|
|
const ObITableEntity *result_entity = NULL;
|
|
{
|
|
batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i*2);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
ObObj c2_obj, c3_obj;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, c3_obj));
|
|
//fprintf(stderr, "%ld (%s,%s)\n", i, S(c2_obj), S(c3_obj));
|
|
ObObj val2, val3;
|
|
if (0 == i % 2) {
|
|
val2.set_int(100+2*i);
|
|
val3.set_varchar(c3_value);
|
|
val3.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
} else {
|
|
val2.set_int(100+i);
|
|
val3.set_varchar(c3_new_value);
|
|
val3.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
}
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_put)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_put"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const int64_t BATCH_PUT_SIZE = 10;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_PUT_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_PUT_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
switch (i % 4) {
|
|
case 0:
|
|
value.set_varbinary(ObString::make_string("string2"));
|
|
break;
|
|
case 1:
|
|
value.set_varbinary(ObString::make_string("string3"));
|
|
break;
|
|
case 2: // row50
|
|
value.set_varbinary(ObString::make_string("string0"));
|
|
break;
|
|
case 3:
|
|
value.set_varbinary(ObString::make_string("string1"));
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity)); // insert
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(1, result.count());
|
|
const ObTableOperationResult &r = result.at(0);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(BATCH_PUT_SIZE * COLUMNS_SIZE * VERSIONS_COUNT, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT_OR_UPDATE, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_mutations)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_mutate"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ASSERT_NO_FATAL_FAILURE(prepare_data(the_table));
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
////////////////////////////////////////////////////////////////
|
|
// row_mutation (cq0->haha, delete cq3, cq5, cq5->kaka)
|
|
ObObj key1, key2, key3, value;
|
|
key1.set_varbinary(ObString::make_string("row0"));
|
|
key2.set_varbinary(ObString::make_string("cq0"));
|
|
key3.set_int(INT64_MAX);
|
|
value.set_varbinary(ObString::make_string("haha"));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
key1.set_varbinary(ObString::make_string("row0"));
|
|
int cqids[] = {3, 5};
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
key3.set_int(-INT64_MAX); // delete all version
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
}
|
|
|
|
key1.set_varbinary(ObString::make_string("row0"));
|
|
key2.set_varbinary(ObString::make_string("cq5"));
|
|
key3.set_int(INT64_MAX);
|
|
value.set_varbinary(ObString::make_string("kaka"));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert_or_update(*entity));
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(1, result.count());
|
|
ASSERT_EQ(OB_SUCCESS, result.at(0).get_errno());
|
|
////////////////////////////////////////////////////////////////
|
|
// verify
|
|
ObTableQuery query;
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, "row0"));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.set_valid(true);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9};
|
|
int64_t timestamps[] = {-1, 9, 9, 9, -1, 9, 9, 9, 9};
|
|
const char* values[] = {"haha", "string2", "string2", "string2",
|
|
"kaka", "string2", "string2", "string2", "string2"};
|
|
for (int64_t i = 0; i < ARRAYSIZEOF(cqids_sorted); ++i) {
|
|
key1.set_varbinary(ObString::make_string("row0"));
|
|
sprintf(qualifier2[i], "cq%d", cqids_sorted[i]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[i]));
|
|
key3.set_int(timestamps[i]);
|
|
value.set_varbinary(ObString::make_string(values[i]));
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
if (timestamps[i] >= 0) {
|
|
ASSERT_EQ(key3, ts);
|
|
}
|
|
ASSERT_EQ(value, val);
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_query_and_mutate)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_query_and_mutate"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
switch (i % 4) {
|
|
case 0:
|
|
value.set_varbinary(ObString::make_string("string2"));
|
|
break;
|
|
case 1:
|
|
value.set_varbinary(ObString::make_string("string3"));
|
|
break;
|
|
case 2: // row50
|
|
value.set_varbinary(ObString::make_string("string0"));
|
|
break;
|
|
case 3:
|
|
value.set_varbinary(ObString::make_string("string1"));
|
|
break;
|
|
default:
|
|
ASSERT_TRUE(0);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE*COLUMNS_SIZE*VERSIONS_COUNT; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// htable filter cases
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, "row50"));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[6] = {0, 3, 1, 4, 7, 9};
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; OB_SUCCESS == ret && i < 6; ++i)
|
|
{
|
|
sprintf(qualifier2[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier2[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
|
|
{
|
|
fprintf(stderr, "case: simple query and put\n");
|
|
// set mutation
|
|
sprintf(rows[0], "row50");
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
key3.set_int(VERSIONS_COUNT);
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j]));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("value_kaka"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.insert_or_update(*entity));
|
|
} // end for
|
|
ObTableQueryAndMutateResult result;
|
|
int64_t &affected_rows = result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
fprintf(stderr, "query_and_mutate affected_rows=%ld\n", affected_rows);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
int64_t timestamps[] = {10};
|
|
for (int64_t i = 0; i < 1; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
{
|
|
fprintf(stderr, "case: simple query and delete columns\n");
|
|
entity_factory.free_and_reuse();
|
|
mutations.reset();
|
|
// set delete mutation
|
|
const char* rowkey = "row50";
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
int cqids_sorted[] = {0, 1, 3, 4, 7, 9};
|
|
// delete version 10 of cq 0, 1, 3, 4, 7, 9
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
key3.set_int(INT64_MAX); // delete latest version
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.del(*entity));
|
|
}
|
|
ObTableQueryAndMutateResult result;
|
|
int64_t &affected_rows = result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
fprintf(stderr, "query_and_mutate affected_rows=%ld\n", affected_rows);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0; i < 1; ++i) {
|
|
// 10 rowkeys
|
|
sprintf(rows[i], "row%ld", i+50);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
{
|
|
fprintf(stderr, "case: hbase checkAndPut (value not null)\n");
|
|
// row50 and row54 will put cq110
|
|
// set query
|
|
htable_filter.clear_columns();
|
|
// select all columns
|
|
for (int64_t j = 0; j < COLUMNS_SIZE; ++j) {
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier[j])));
|
|
}
|
|
htable_filter.set_filter(ObString::make_string("CheckAndMutateFilter(=, 'substring:string0', 'cf1', 'cq1', false)"));
|
|
ObNewRange range;
|
|
// set mutation
|
|
for (int64_t i = 0; i < 8; ++i) { // row50 ~ row57
|
|
sprintf(rows[0], "row%ld", 50+i);
|
|
pk_objs_start[0].set_varbinary(ObString::make_string(rows[0]));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
pk_objs_end[0].set_varbinary(ObString::make_string(rows[0]));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
query.clear_scan_range();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
entity_factory.free_and_reuse();
|
|
mutations.reset();
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
key3.set_int(VERSIONS_COUNT);
|
|
key2.set_varbinary(ObString::make_string("cq110"));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("string110"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.insert_or_update(*entity));
|
|
ObTableQueryAndMutateResult result;
|
|
int64_t &affected_rows = result.affected_rows_;
|
|
ret = the_table->execute_query_and_mutate(query_and_mutate, result);
|
|
if (i % 4 == 0) {
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_EQ(1, affected_rows);
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_EQ(0, affected_rows); // affected_rows should be 0 when check failed
|
|
}
|
|
} // end for
|
|
|
|
// scan row50 ~ row57
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row58"));
|
|
pk_objs_end[1].set_min_value();
|
|
pk_objs_end[2].set_min_value();
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.unset_inclusive_end();
|
|
query.clear_scan_range();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
htable_filter.reset();
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string("cq110")));
|
|
htable_filter.set_valid(true);
|
|
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {110};
|
|
int64_t timestamps[] = {VERSIONS_COUNT};
|
|
for (int64_t i = 0; i < 2; ++i) {
|
|
// 2 rows
|
|
if (i == 0) {
|
|
sprintf(rows[0], "row50");
|
|
} else {
|
|
sprintf(rows[0], "row54");
|
|
}
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
|
|
{
|
|
fprintf(stderr, "case: hbase checkAndDelete (value is null)\n");
|
|
// assert: columns except row50 and row54 will be deleted
|
|
// set query
|
|
htable_filter.set_max_versions(INT32_MAX);
|
|
htable_filter.clear_columns();
|
|
htable_filter.set_filter(ObString::make_string("CheckAndMutateFilter(=, 'substring:string0', 'cf1', 'cq110', true)"));
|
|
ObNewRange range;
|
|
// set mutation
|
|
for (int64_t i = 0; i < 8; ++i) { // row50 ~ row57
|
|
sprintf(rows[0], "row%ld", 50+i);
|
|
pk_objs_start[0].set_varbinary(ObString::make_string(rows[0]));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
pk_objs_end[0].set_varbinary(ObString::make_string(rows[0]));
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
query.clear_scan_range();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
entity_factory.free_and_reuse();
|
|
mutations.reset();
|
|
// delete row iff check succeed
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
key2.set_null(); // delete all qualifier
|
|
key3.set_int(-INT64_MAX); // delete latest version
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.del(*entity));
|
|
ObTableQueryAndMutateResult result;
|
|
int64_t &affected_rows = result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
fprintf(stderr, "query_and_mutate affected_rows=%ld\n", affected_rows);
|
|
if (i % 4 == 0) {
|
|
ASSERT_EQ(0, affected_rows);
|
|
} else {
|
|
ASSERT_EQ(1, affected_rows);
|
|
}
|
|
} // end for
|
|
|
|
// scan row50 ~ row57
|
|
pk_objs_start[0].set_varbinary(ObString::make_string("row50"));
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
pk_objs_end[0].set_varbinary(ObString::make_string("row58"));
|
|
pk_objs_end[1].set_min_value();
|
|
pk_objs_end[2].set_min_value();
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.unset_inclusive_end();
|
|
query.clear_scan_range();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
htable_filter.reset();
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string("cq0")));
|
|
htable_filter.set_max_versions(1);
|
|
htable_filter.set_valid(true);
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0};
|
|
int64_t timestamps[] = {9};
|
|
for (int64_t i = 0; i < 2; ++i) {
|
|
// 2 rows
|
|
if (i == 0) {
|
|
sprintf(rows[0], "row50");
|
|
} else {
|
|
sprintf(rows[0], "row54");
|
|
}
|
|
key1.set_varbinary(ObString::make_string(rows[0]));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
// 4 qualifier
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
for (int64_t k = 0; k < ARRAYSIZEOF(timestamps); ++k)
|
|
{
|
|
key3.set_int(timestamps[k]);
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
//fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(key3, ts);
|
|
} // end for
|
|
}
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_increment)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_increment"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
char values[VERSIONS_COUNT][8];
|
|
for (int i = 0; i < VERSIONS_COUNT; ++i) {
|
|
ObHTableUtils::int64_to_java_bytes(i, values[i]);
|
|
}
|
|
const char* rowkey = "row0";
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE/2; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j*2])); // cq0, cq2, cq4, ... cq8
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ObString str(8, values[j*2]);
|
|
value.set_varbinary(str);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(1*COLUMNS_SIZE/2*VERSIONS_COUNT, result.count());
|
|
////////////////////////////////////////////////////////////////
|
|
// case
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[] = {8, 7, 6, 5, 4, 3, 2, 1};
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; OB_SUCCESS == ret && i < ARRAYSIZEOF(cqids); ++i)
|
|
{
|
|
sprintf(qualifier2[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier2[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
|
|
// do increment
|
|
mutations.reset();
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids); ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
key3.set_int(VERSIONS_COUNT);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ObString v_str(8, values[j]);
|
|
value.set_varbinary(v_str);
|
|
// 8 + 0, 7 + 1, ... 1 + 7
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.increment(*entity));
|
|
}
|
|
ObTableQueryAndMutateResult inc_result;
|
|
int64_t &affected_rows = inc_result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, inc_result));
|
|
fprintf(stderr, "affected_rows=%ld\n", affected_rows);
|
|
{
|
|
int64_t num = 0;
|
|
int64_t new_int = 0;
|
|
ObObj val;
|
|
ObString str;
|
|
const ObITableEntity *result_entity = NULL;
|
|
while(OB_SUCC(inc_result.affected_entity_.get_next_entity(result_entity))) {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(OB_SUCCESS, ObHTableUtils::java_bytes_to_int64(str, new_int));
|
|
// fprintf(stderr, "%s | %ld\n", S(*result_entity), new_int);
|
|
num++;
|
|
if (num % 2 == 0) {
|
|
ASSERT_EQ(8, new_int);
|
|
} else {
|
|
ASSERT_EQ(8-num, new_int);
|
|
}
|
|
}
|
|
ASSERT_EQ(num, ARRAYSIZEOF(cqids));
|
|
}
|
|
// verify result
|
|
htable_filter.clear_columns();
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
int64_t expected_int = 0;
|
|
ObString str;
|
|
int64_t read_int = 0;
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
if (j == 0 || j == 8) {
|
|
expected_int = j;
|
|
if (j == 8) {
|
|
// version is now()
|
|
key3.set_null();
|
|
} else {
|
|
key3.set_int(9);
|
|
}
|
|
} else if (j % 2==0) {
|
|
expected_int = 8;
|
|
// version is now()
|
|
key3.set_null();
|
|
} else {
|
|
expected_int = 8-j; // first write
|
|
key3.set_int(VERSIONS_COUNT);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(OB_SUCCESS, ObHTableUtils::java_bytes_to_int64(str, read_int));
|
|
// fprintf(stderr, "(%s,%s,%s,%s(%ld))\n", S(rk), S(cq), S(ts), S(val), read_int);
|
|
UNUSED(expected_int);
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
if (!key3.is_null()) {
|
|
ASSERT_EQ(key3, ts);
|
|
}
|
|
ASSERT_EQ(read_int, expected_int);
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_increment_empty)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_increment_empty"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
char values[VERSIONS_COUNT][8];
|
|
for (int i = 0; i < VERSIONS_COUNT; ++i) {
|
|
ObHTableUtils::int64_to_java_bytes(i, values[i]);
|
|
}
|
|
const char* rowkey = "row1";
|
|
////////////////////////////////////////////////////////////////
|
|
// case
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[] = {8, 7, 6, 5, 4, 3, 2, 1};
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; OB_SUCCESS == ret && i < ARRAYSIZEOF(cqids); ++i)
|
|
{
|
|
sprintf(qualifier2[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier2[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
|
|
// do increment
|
|
mutations.reset();
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids); ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
key3.set_int(VERSIONS_COUNT);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ObString v_str(8, values[j]);
|
|
value.set_varbinary(v_str);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.increment(*entity));
|
|
}
|
|
ObTableQueryAndMutateResult inc_result;
|
|
int64_t &affected_rows = inc_result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, inc_result));
|
|
fprintf(stderr, "affected_rows=%ld\n", affected_rows);
|
|
{
|
|
int64_t num = 0;
|
|
int64_t new_int = 0;
|
|
ObObj val;
|
|
ObString str;
|
|
const ObITableEntity *result_entity = NULL;
|
|
while(OB_SUCC(inc_result.affected_entity_.get_next_entity(result_entity))) {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(OB_SUCCESS, ObHTableUtils::java_bytes_to_int64(str, new_int));
|
|
//fprintf(stderr, "%s | %ld\n", S(*result_entity), new_int);
|
|
num++;
|
|
ASSERT_EQ(8-num, new_int);
|
|
}
|
|
ASSERT_EQ(num, ARRAYSIZEOF(cqids));
|
|
}
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_increment_multi_thread)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_increment"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
|
|
// 1. execute delete first
|
|
const char* rowkey = "row2";
|
|
const char *qualifier = "cq1";
|
|
ObObj key1, key2, key3, value;
|
|
entity = entity_factory.alloc();
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
key2.set_varbinary(ObString::make_string(qualifier));
|
|
key3.set_int(-INT64_MAX); // delete all versions
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.del(*entity));
|
|
ObTableBatchOperationResult del_result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, del_result));
|
|
////////////////////////////////////////////////////////////////
|
|
// 2. fill query and mutations
|
|
// query: query with row0 and htable filter for column cq0
|
|
// mutation: row2, cq1, 1, 1
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
ASSERT_EQ(1, htable_filter.get_max_versions());
|
|
htable_filter.set_valid(true);
|
|
mutations.reset();
|
|
entity->reset();
|
|
key3.set_int(INT64_MAX); // latest time
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
char inc_value[8];
|
|
ObHTableUtils::int64_to_java_bytes(1, inc_value);
|
|
ObString inc_str(8, inc_value);
|
|
value.set_varbinary(inc_str);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.increment(*entity));
|
|
// 3. execute increment and check result
|
|
auto task = [&](ObTable* one_table, const ObTableQueryAndMutate &query_and_mutate, uint64_t inc_times) {
|
|
ObTableQueryAndMutateResult inc_result;
|
|
for (int i = 0; i < inc_times; i++) {
|
|
ASSERT_EQ(OB_SUCCESS, one_table->execute_query_and_mutate(query_and_mutate, inc_result));
|
|
ASSERT_EQ(1, inc_result.affected_rows_);
|
|
}
|
|
};
|
|
constexpr uint64_t thread_num = 30;
|
|
constexpr uint64_t inc_times = 50;
|
|
std::vector<std::thread> threads;
|
|
time_t start_time = time(NULL);
|
|
printf("begin to run tasks, thread_num: %ld\n", thread_num);
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
std::thread t(task, the_table, query_and_mutate, inc_times);
|
|
threads.push_back(std::move(t));
|
|
}
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
threads.at(i).join();
|
|
}
|
|
printf("time elapsed during query process: %lfs\n", double(time(NULL) - start_time));
|
|
|
|
// 4. execute query and verify result
|
|
htable_filter.clear_columns();
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
key2.set_varbinary(ObString::make_string(qualifier));
|
|
int64_t read_int = 0;
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(OB_SUCCESS, ObHTableUtils::java_bytes_to_int64(str, read_int));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
// ASSERT_EQ(key3, ts);
|
|
std::cout << "key3: " << ts.get_int() << std::endl;
|
|
ASSERT_EQ(read_int, thread_num * inc_times);
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
TEST_F(TestBatchExecute, htable_append)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_append"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
static constexpr int64_t COLUMNS_SIZE = 10;
|
|
char qualifier[COLUMNS_SIZE][128];
|
|
for (int i = 0; i < COLUMNS_SIZE; ++i)
|
|
{
|
|
sprintf(qualifier[i], "cq%d", i);
|
|
} // end for
|
|
char values[VERSIONS_COUNT][128];
|
|
for (int i = 0; i < VERSIONS_COUNT; ++i) {
|
|
sprintf(values[i], "ob%d", i);
|
|
}
|
|
const char* rowkey = "row0";
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < COLUMNS_SIZE/2; ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier[j*2])); // cq0, cq2, cq4, ... cq8
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string(values[j*2]));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(1*COLUMNS_SIZE/2*VERSIONS_COUNT, result.count());
|
|
////////////////////////////////////////////////////////////////
|
|
// case
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
int cqids[] = {8, 7, 6, 5, 4, 3, 2, 1};
|
|
char qualifier2[COLUMNS_SIZE][128];
|
|
for (int i = 0; OB_SUCCESS == ret && i < ARRAYSIZEOF(cqids); ++i)
|
|
{
|
|
sprintf(qualifier2[i], "cq%d", cqids[i]);
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string(qualifier2[i])));
|
|
} // end for
|
|
htable_filter.set_valid(true);
|
|
|
|
// do append
|
|
mutations.reset();
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids); ++j) {
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
key3.set_int(VERSIONS_COUNT);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ObString v_str = ObString::make_string(values[j]);
|
|
value.set_varbinary(v_str);
|
|
// 8 + 0, 7 + 1, ... 1 + 7
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.append(*entity));
|
|
}
|
|
ObTableQueryAndMutateResult inc_result;
|
|
int64_t &affected_rows = inc_result.affected_rows_;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, inc_result));
|
|
fprintf(stderr, "affected_rows=%ld\n", affected_rows);
|
|
{
|
|
int64_t num = 0;
|
|
ObObj val;
|
|
ObString str;
|
|
const ObITableEntity *result_entity = NULL;
|
|
while(OB_SUCC(inc_result.affected_entity_.get_next_entity(result_entity))) {
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
// fprintf(stderr, "%s\n", S(*result_entity));
|
|
num++;
|
|
// if (num % 2 == 0) {
|
|
// ASSERT_EQ(8, new_int);
|
|
// } else {
|
|
// ASSERT_EQ(8-num, new_int);
|
|
// }
|
|
}
|
|
ASSERT_EQ(num, ARRAYSIZEOF(cqids));
|
|
}
|
|
// verify result
|
|
htable_filter.clear_columns();
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int cqids_sorted[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
char expected_str[128];
|
|
ObString str;
|
|
for (int64_t j = 0; j < ARRAYSIZEOF(cqids_sorted); ++j) {
|
|
sprintf(qualifier2[j], "cq%d", cqids_sorted[j]);
|
|
key2.set_varbinary(ObString::make_string(qualifier2[j]));
|
|
if (j == 0) {
|
|
sprintf(expected_str, "ob%ld", j);
|
|
key3.set_int(9);
|
|
} else if (j % 2==0) {
|
|
sprintf(expected_str, "ob%ldob%ld", j, 8-j);
|
|
// version is now()
|
|
key3.set_null();
|
|
} else {
|
|
sprintf(expected_str, "ob%ld", 8-j); // first write
|
|
key3.set_int(VERSIONS_COUNT);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
// fprintf(stderr, "(%s,%s,%s,%s)\n", S(rk), S(cq), S(ts), S(val));
|
|
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
if (!key3.is_null()) {
|
|
ASSERT_EQ(key3, ts);
|
|
}
|
|
ASSERT_TRUE(0 == str.compare(ObString::make_string(expected_str)));
|
|
} // end for
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists query_sync_multi_batch_test (PK1 bigint, PK2 bigint, C1 bigint, C2 varchar(100), C3 bigint, PRIMARY KEY(PK1, PK2), INDEX idx1(C1, C2));
|
|
TEST_F(TestBatchExecute, query_sync_multi_batch)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("query_sync_multi_batch_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i%5);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObObj value;
|
|
value.set_int(100+i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C1, value));
|
|
value.set_varchar(ObString::make_string("c2_value"));
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
printf("insert data into query_sync_multi_batch_test using batch_execute...\n");
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(BATCH_SIZE, result.count());
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
|
|
// cases
|
|
printf("begin to execute query...\n");
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(PK2));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_int(0);
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_offset(5);
|
|
query.set_limit(10);
|
|
query.set_batch(1);
|
|
query.set_scan_index(ObString::make_string("primary"));
|
|
ObQueryFlag::ScanOrder scan_orders[2] = { ObQueryFlag::Forward, ObQueryFlag::Reverse };
|
|
for (int k = 0; k < 2; ++k)
|
|
{
|
|
// two scan order
|
|
query.set_scan_order(scan_orders[k]);
|
|
ObTableQuerySyncResult *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
int result_cnt = 0;
|
|
for (int64_t i = 5; i < 15; ++i)
|
|
{
|
|
// printf("start to get entity from result iterator, i: %ld, result_cnt: %d\n", i, result_cnt);
|
|
ASSERT_EQ(1, iter->get_row_count());
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(4, result_entity->get_properties_count());
|
|
|
|
ObObj value;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, value));
|
|
if (0 == k) {
|
|
ASSERT_EQ(100+i*5, value.get_int());
|
|
} else {
|
|
ASSERT_EQ(100+(19-i)*5, value.get_int());
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, value.get_varchar(str));
|
|
ASSERT_TRUE(str == ObString::make_string("c2_value"));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, value));
|
|
ASSERT_TRUE(value.is_null());
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(PK2, value));
|
|
if (0 == k) {
|
|
ASSERT_EQ(i*5, value.get_int());
|
|
} else {
|
|
ASSERT_EQ((19-i)*5, value.get_int());
|
|
}
|
|
++result_cnt;
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
if (i == 14) {
|
|
ASSERT_EQ(OB_ITER_END, the_table->query_next(iter));
|
|
ASSERT_EQ(0, iter->get_row_count());
|
|
} else {
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_next(iter));
|
|
}
|
|
}
|
|
ASSERT_EQ(query.get_limit(), result_cnt);
|
|
} // end for
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists htable1_query_sync (
|
|
// K varbinary(1024), Q varbinary(256), T bigint, V varbinary(1024),
|
|
// primary key(K, Q, T));
|
|
TEST_F(TestBatchExecute, htble_query_sync)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_query_sync"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
////////////////////////////////////////////////////////////////
|
|
static constexpr int64_t VERSIONS_COUNT = 10;
|
|
DefaultBuf *rows = new (std::nothrow) DefaultBuf[BATCH_SIZE];
|
|
ASSERT_TRUE(NULL != rows);
|
|
ObObj key1, key2, key3;
|
|
ObObj value;
|
|
for (int64_t i = 0; i < BATCH_SIZE; ++i) {
|
|
sprintf(rows[i], "row%ld", i);
|
|
key1.set_varbinary(ObString::make_string(rows[i]));
|
|
key2.set_varbinary(ObString::make_string("")); // empty qualifier
|
|
for (int64_t k = 0; k < VERSIONS_COUNT; ++k)
|
|
{
|
|
key3.set_int(k);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(ObString::make_string("value_string"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
} // end for
|
|
} // end for
|
|
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
OB_LOG(INFO, "batch execute result", K(result));
|
|
ASSERT_EQ(BATCH_SIZE*VERSIONS_COUNT, result.count());
|
|
////////////////////////////////////////////////////////////////
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(K));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(Q));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(T));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(V));
|
|
ObObj pk_objs_start[3];
|
|
pk_objs_start[0].set_min_value();
|
|
pk_objs_start[1].set_min_value();
|
|
pk_objs_start[2].set_min_value();
|
|
ObObj pk_objs_end[3];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
pk_objs_end[2].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 3);
|
|
range.end_key_.assign(pk_objs_end, 3);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
ASSERT_EQ(OB_SUCCESS, htable_filter.add_column(ObString::make_string("")));
|
|
htable_filter.set_max_versions(2);
|
|
htable_filter.set_valid(true);
|
|
const int64_t query_round = 4;
|
|
query.set_batch(50);
|
|
|
|
ObTableQuerySyncResult *iter = nullptr;
|
|
const ObITableEntity *result_entity = NULL;
|
|
uint64_t result_cnt = 0;
|
|
uint64_t round = 0;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
while (OB_SUCC(the_table->query_next(iter))) {
|
|
++round;
|
|
// printf("iterator row count: %ld\n", iter->get_row_count());
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
printf("round: %ld\n", round);
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(200, result_cnt); // set_max_versions(2),故只有200条
|
|
ASSERT_EQ(round, query_round - 1); // start已经扫描了一次
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
delete [] rows;
|
|
}
|
|
|
|
// create table if not exists large_scan_query_sync_test (C1 bigint primary key, C2 bigint, C3 varchar(100));
|
|
TEST_F(TestBatchExecute, large_scan_query_sync)
|
|
{
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("large_scan_query_sync_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
//prepare data
|
|
const int64_t large_batch_size = 10000;
|
|
const int64_t query_round = 4;
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
for (int64_t i = 0; i < large_batch_size; ++i) {
|
|
entity->reset();
|
|
key.set_int(key_key + i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
entity->reset();
|
|
|
|
// forward scan
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("primary"));
|
|
query.set_scan_order(ObQueryFlag::Forward);
|
|
query.set_batch(large_batch_size / query_round);
|
|
|
|
ObTableQuerySyncResult *iter = nullptr;
|
|
uint64_t result_cnt = 0;
|
|
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
do {
|
|
// printf("iterator row count: %ld\n", iter->get_row_count());
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(large_batch_size, result_cnt);
|
|
|
|
//reverse scan
|
|
query.set_scan_order(ObQueryFlag::Reverse);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
result_cnt = 0;
|
|
do {
|
|
// printf("iterator row count: %ld\n", iter->get_row_count());
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, large_batch_size);
|
|
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists query_sync_with_index_test
|
|
// (C1 bigint, C2 bigint, C3 bigint,
|
|
// primary key(C1, C2), KEY idx_c2 (C2), KEY idx_c3 (C3), KEY idx_c2c3(C2, C3));
|
|
TEST_F(TestBatchExecute, query_sync_with_index)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("query_sync_with_index_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
ObTableQuerySyncResult *iter = nullptr;
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
int64_t key_key = 1;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 1;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
|
|
//prepare data
|
|
const int64_t batch_size = 100;
|
|
const int64_t query_round = 5;
|
|
for (int64_t i = 0; i < batch_size; ++i) {
|
|
entity->reset();
|
|
key.set_int(key_key + i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
entity->reset();
|
|
|
|
//scan
|
|
ObTableQuery query;
|
|
{
|
|
// case 1: primary key
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_batch(batch_size / query_round));
|
|
int64_t result_cnt = 0;
|
|
do {
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size);
|
|
}
|
|
|
|
{
|
|
// case 2: index is the subset of primary key
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c2")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_batch(batch_size / query_round));
|
|
int64_t result_cnt = 0;
|
|
do {
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size);
|
|
}
|
|
|
|
{
|
|
// case 3: has itersection between primary key and index
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start[2];
|
|
pk_objs_start[0].set_int(0);
|
|
pk_objs_start[1].set_min_value();
|
|
ObObj pk_objs_end[2];
|
|
pk_objs_end[0].set_max_value();
|
|
pk_objs_end[1].set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(pk_objs_start, 2);
|
|
range.end_key_.assign(pk_objs_end, 2);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c2c3")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_batch(batch_size / query_round));
|
|
int64_t result_cnt = 0;
|
|
do {
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size);
|
|
}
|
|
|
|
{
|
|
// case 4: has no itersection between primary key and index
|
|
query.reset();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("idx_c3")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->query_start(query, iter));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_batch(batch_size / query_round));
|
|
int64_t result_cnt = 0;
|
|
do {
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
++result_cnt;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
} while (OB_SUCC(the_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size);
|
|
}
|
|
|
|
// teardown
|
|
iter = nullptr;
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// create table if not exists query_sync_multi_task_test
|
|
// (C1 bigint primary key, C2 bigint, C3 varchar(100));
|
|
TEST_F(TestBatchExecute, query_sync_multi_task)
|
|
{
|
|
// setup
|
|
constexpr int64_t thread_num = 10;
|
|
const int64_t large_batch_size = 1000;
|
|
int64_t query_round = 10;
|
|
const int64_t query_batch_size = large_batch_size / query_round;
|
|
ObVector<ObTable *> tables;
|
|
|
|
printf("create client table handle\n");
|
|
ObTable *the_table;
|
|
ObTableRequestOptions request_options;
|
|
request_options.set_returning_affected_rows(true);
|
|
request_options.set_server_timeout(120*1000*1000); // 120s
|
|
for (int64_t i = 0; i < thread_num; ++i) {
|
|
the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("query_sync_multi_task_test"), the_table);
|
|
OB_LOG(INFO, "alloc_table succeed", K(i));
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_default_request_options(request_options);
|
|
tables.push_back(the_table);
|
|
}
|
|
|
|
printf("prepare data\n");
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
ObTableBatchOperation batch_operation;
|
|
int64_t key_key = 139107;
|
|
ObObj key;
|
|
key.set_int(key_key);
|
|
int64_t value_value = 33521;
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
|
|
// prepare data
|
|
ObString c3_value = ObString::make_string("hello world");
|
|
clock_t start = clock();
|
|
for (int64_t i = 0; i < large_batch_size; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(key_key + i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObObj value;
|
|
value.set_int(value_value);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_varchar(c3_value);
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, batch_operation.insert(*entity));
|
|
}
|
|
printf("time elapsed during data preparation: %lfs\n", double(clock() - start) / CLOCKS_PER_SEC);
|
|
start = clock();
|
|
ASSERT_TRUE(!batch_operation.is_readonly());
|
|
ASSERT_TRUE(batch_operation.is_same_type());
|
|
ASSERT_TRUE(batch_operation.is_same_properties_names());
|
|
ObTableBatchOperationResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(batch_operation, result));
|
|
ASSERT_EQ(large_batch_size, result.count());
|
|
printf("time elapsed during batch_execute: %lfs\n", double(clock() - start) / CLOCKS_PER_SEC);
|
|
|
|
start = clock();
|
|
for (int64_t i = 0; i < large_batch_size; ++i)
|
|
{
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
} // end for
|
|
printf("time elapsed during batch_execute result check: %lfs\n", double(clock() - start) / CLOCKS_PER_SEC);
|
|
|
|
// forward scan
|
|
ObTableQuery query;
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(0);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
query.set_scan_index(ObString::make_string("primary"));
|
|
query.set_batch(query_batch_size); // ensure multiple threads handle one query
|
|
query.set_scan_order(ObQueryFlag::Forward);
|
|
|
|
auto task = [&](ObTable * one_table) {
|
|
int ret;
|
|
ObTableQuerySyncResult *iter = nullptr;
|
|
uint64_t result_cnt = 0;
|
|
ObObj one_value;
|
|
const ObITableEntity *one_result_entity = NULL;
|
|
|
|
ASSERT_EQ(OB_SUCCESS, one_table->query_start(query, iter));
|
|
do {
|
|
OB_LOG(INFO, "start to do query sync task", K(iter->get_row_count()));
|
|
while (OB_SUCC(iter->get_next_entity(one_result_entity))) {
|
|
ASSERT_EQ(OB_SUCCESS, one_result_entity->get_property(C1, one_value));
|
|
ASSERT_EQ(key_key + result_cnt, one_value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, one_result_entity->get_property(C2, one_value));
|
|
ASSERT_EQ(value_value, one_value.get_int());
|
|
ASSERT_EQ(OB_SUCCESS, one_result_entity->get_property(C3, one_value));
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, one_value.get_varchar(str));
|
|
ASSERT_EQ(c3_value, str);
|
|
++result_cnt;
|
|
}
|
|
} while (OB_SUCC(one_table->query_next(iter)));
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(large_batch_size, result_cnt);
|
|
|
|
OB_LOG(INFO, "finsh query sync task", K(result_cnt));
|
|
};
|
|
|
|
std::vector<std::thread> threads;
|
|
uint64_t N = tables.size();
|
|
ASSERT_EQ(thread_num, N);
|
|
|
|
time_t start_time = time(NULL);
|
|
printf("begin to run tasks, thread_num: %ld, large_batch_size: %ld, query_round: %ld\n", thread_num, large_batch_size, query_round);
|
|
for (uint64_t i = 0; i < N; ++i) {
|
|
std::thread t(task, tables.at(i));
|
|
threads.push_back(std::move(t));
|
|
}
|
|
for (uint64_t i = 0; i < N; ++i) {
|
|
threads.at(i).join();
|
|
}
|
|
printf("time elapsed during query process: %lfs\n", double(time(NULL) - start_time));
|
|
|
|
// teardown
|
|
for (uint64_t i = 0; i < N; ++i) {
|
|
service_client_->free_table(tables.at(i));
|
|
}
|
|
}
|
|
|
|
// create table if not exists query_with_filter (C1 bigint primary key, C2 bigint default null, C3 varchar(100) default null, C4 double default 0);
|
|
TEST_F(TestBatchExecute, table_query_with_filter)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("query_with_filter"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
ObTableEntityIterator *iter = nullptr;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObString s1 = ObString::make_string("hello c++");
|
|
ObString s2 = ObString::make_string("hello java");
|
|
ObString C4 = ObString::make_string("C4");
|
|
//prepare data
|
|
const int64_t batch_size = 100;
|
|
for (int64_t i = 1; i <= batch_size; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_double(1.0 * i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar(s1);
|
|
} else {
|
|
value.set_varchar(s2);
|
|
}
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
//scan
|
|
ObTableQuery query;
|
|
{
|
|
// case 1: normal case
|
|
fprintf(stderr, "case 1: normal query\n");
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_min_value();
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size);
|
|
} // end case 1
|
|
{
|
|
// case 2: normal case filter C3='hello c++'
|
|
fprintf(stderr, "case 2: TableCompareFilter(=, 'C3:hello c++')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_min_value();
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_max_value();
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello c++')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(0, v3.get_varchar().compare("hello c++"));
|
|
// fprintf(stderr, "(%ld, %ld,%ld,%s)\n", result_cnt, v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(result_cnt, batch_size/2);
|
|
} // end case 2
|
|
{
|
|
// case 3: normal case filter C2=50
|
|
fprintf(stderr, "case 3: TableCompareFilter(=, 'C2:50')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(30);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(100);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C2:50')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(50, v2.get_int());
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(1, result_cnt);
|
|
} // end case 3
|
|
{
|
|
// case 4: normal case filter C2>=50
|
|
fprintf(stderr, "case 4: TableCompareFilter(>=, 'C2:50')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(30);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(55);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>=, 'C2:50')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_GE(v2.get_int(), 50);
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(6, result_cnt);
|
|
} // end case 4
|
|
{
|
|
// case 5: normal case filter C2 < 50
|
|
fprintf(stderr, "case 5: TableCompareFilter(<, 'C2:50')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(40);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(55);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:50')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_LE(v2.get_int(), 50);
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
} // end case 5
|
|
{
|
|
// case 6: bad filter case, filter column is not in select columns
|
|
fprintf(stderr, "case 6: select columns {C1, C3}, filter_string=TableCompareFilter(<, 'C2:50')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(40);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(55);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:50')")));
|
|
int ret = the_table->execute_query(query, iter);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_LE(v1.get_int(), 50);
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(10, result_cnt);
|
|
// fprintf(stderr, "query ret=%d\n", ret);
|
|
} // end case 6
|
|
{
|
|
// case 7: bad filter case, data type error
|
|
fprintf(stderr, "case 7: data type bad case, filter_string=TableCompareFilter(=, 'C4:50')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(40);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(55);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C4:50')")));
|
|
int ret = the_table->execute_query(query, iter);
|
|
ASSERT_NE(OB_SUCCESS, ret);
|
|
// fprintf(stderr, "query ret=%d\n", ret);
|
|
} // end case 7
|
|
{
|
|
// case 8: more than one `:` in filter string
|
|
// fprintf(stderr, "case 8: more than one `:` in filter string, filter_string=TableCompareFilter(=, 'C3:hello:c++')\n");
|
|
// data update
|
|
for (int64_t i = 1; i <= batch_size; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar("hello:c++");
|
|
} else {
|
|
value.set_varchar("hello:java");
|
|
}
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(11);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(20);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello:c++')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
} // end case 8
|
|
{
|
|
// case 9: int border value
|
|
fprintf(stderr, "case 9 int border value\n");
|
|
// data update
|
|
for (int64_t i = 1; i <= batch_size; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
if (i % 2 == 0) {
|
|
value.set_int(INT64_MAX);
|
|
} else {
|
|
value.set_int(INT64_MIN);
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
table_operation = ObTableOperation::update(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::UPDATE, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
fprintf(stderr, "case 9-1 filter_string=TableCompareFilter(>=, 'C2:9223372036854775807')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(1);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(20);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>=, 'C2:9223372036854775807')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
fprintf(stderr, "case 9-2 filter_string=TableCompareFilter(<, 'C2:9223372036854775807')\n");
|
|
query.reset();
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
|
|
pk_objs_start.set_int(1);
|
|
pk_objs_end.set_int(20);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:9223372036854775807')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
fprintf(stderr, "case 9-3 filter_string=TableCompareFilter(<, 'C2:-9223372036854775807')\n");
|
|
query.reset();
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
pk_objs_start.set_int(1);
|
|
pk_objs_end.set_int(20);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:-9223372036854775807')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
fprintf(stderr, "case 9-4 filter_string=TableCompareFilter(<, 'C2:9223372036854775808'), trigeer border problem\n");
|
|
query.reset();
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
pk_objs_start.set_int(1);
|
|
pk_objs_end.set_int(20);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:9223372036854775808')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
fprintf(stderr, "case 9-5 filter_string=TableCompareFilter(>, 'C2:-9223372036854775809'), trigeer border problem\n");
|
|
query.reset();
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C4));
|
|
pk_objs_start.set_int(1);
|
|
pk_objs_end.set_int(20);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>, 'C2:-9223372036854775809')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, v4));
|
|
// fprintf(stderr, "(%ld,%ld,%.2f,%s)\n", v1.get_int(), v2.get_int(), v4.get_double(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
} // end case 9
|
|
{
|
|
// case 10 check stirng upper/lower
|
|
fprintf(stderr, "case 10 check stirng upper/lower, filter string=TableCompareFilter(=, 'C3:hello:JAVA')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(31);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(40);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello:JAVA')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(0, v3.get_varchar().compare("hello:java"));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
} // end case 10
|
|
{
|
|
// case 11 empty string compare, filter_string=TableCompareFilter(=, 'C3:')
|
|
fprintf(stderr, "case 11 empty string compare, filter_string=TableCompareFilter(=, 'C3:')\n");
|
|
// insert some data
|
|
for (int64_t i = 101; i <= 120; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_double(1.0 * i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar(s1);
|
|
} else {
|
|
value.set_varchar("");
|
|
}
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(101);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(110);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(0, v3.get_varchar().compare(""));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
} // end case 11
|
|
{
|
|
// case 12 string non-equality
|
|
fprintf(stderr, "case 12 string non-equality, filter_string=TableCompareFilter(>, 'C3:g')\n");
|
|
// insert some data
|
|
for (int64_t i = 121; i <= 140; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_double(1.0 * i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, value));
|
|
std::string s;
|
|
s.push_back('a' + (i - 121));
|
|
value.set_varchar(s.c_str());
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(121);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(130);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>, 'C3:g')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(3, result_cnt);
|
|
} // end case 12
|
|
{
|
|
// case 13 null field
|
|
fprintf(stderr, "case 13 null field\n");
|
|
// insert some data
|
|
for (int64_t i = 141; i <= 160; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
if (i % 2 != 0) {
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
}
|
|
if (i % 2 == 0) {
|
|
value.set_varchar("hello world");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
}
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
fprintf(stderr, "case 13-1 filter_string=TableCompareFilter(!=, 'C3:hello world')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(141);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(150);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(!=, 'C3:hello world')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int64_t result_cnt = 0;
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(0, result_cnt);
|
|
fprintf(stderr, "case 13-2 filter_string=TableCompareFilter(!=, 'C3:155')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(151);
|
|
pk_objs_end.set_int(160);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(!=, 'C2:155')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(4, result_cnt);
|
|
fprintf(stderr, "case 13-3 filter_string=TableCompareFilter(>, 'C2:155')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(151);
|
|
pk_objs_end.set_int(160);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>, 'C2:155')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(2, result_cnt);
|
|
} // end case 13
|
|
{
|
|
// case 14 compare string contains '\''
|
|
fprintf(stderr, "case 14 compare string contains `'`\n");
|
|
// insert some data
|
|
for (int64_t i = 171; i <= 190; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar("hello'quote");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
}
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(171);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(180);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello\'quote')")));
|
|
ASSERT_EQ(OB_ERR_PARSER_SYNTAX, the_table->execute_query(query, iter));
|
|
} // end case 14
|
|
{
|
|
// case 15 filter and
|
|
fprintf(stderr, "case 15 filter list\n");
|
|
fprintf(stderr, "case 15-1 filter_string=TableCompareFilter(=, 'C3:hello c++') && TableCompareFilter(>, 'C2:110')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(101);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(120);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello c++') && TableCompareFilter(>, 'C2:110')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3, v4;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
fprintf(stderr, "case 15-2 filter_string=TableCompareFilter(>, 'C2:170') && TableCompareFilter(<=, 'C2:180')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(170);
|
|
pk_objs_end.set_int(190);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>, 'C2:170') && TableCompareFilter(<=, 'C2:180')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(10, result_cnt);
|
|
fprintf(stderr, "case 15-3 filter_string=TableCompareFilter(>=, 'C3:d') && TableCompareFilter(<, 'C3:p')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(121);
|
|
pk_objs_end.set_int(140);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>=, 'C3:d') && TableCompareFilter(<, 'C3:p')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(('p'-'d'), result_cnt);
|
|
fprintf(stderr, "case 15-4 filter_string=TableCompareFilter(<, 'C3:d') && TableCompareFilter(>, 'C3:p')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(121);
|
|
pk_objs_end.set_int(140);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C3:d') && TableCompareFilter(>, 'C3:p')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(0, result_cnt);
|
|
fprintf(stderr, "case 15-5 filter_string=TableCompareFilter(<, 'C3:d') || TableCompareFilter(>, 'C3:p')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(121);
|
|
pk_objs_end.set_int(140);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C3:d') || TableCompareFilter(>, 'C3:p')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(7, result_cnt);
|
|
fprintf(stderr, "case 15-6 filter_string=TableCompareFilter(>, 'C2:110') || TableCompareFilter(!=, 'C3:')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.reset();
|
|
pk_objs_end.reset();
|
|
range.reset();
|
|
pk_objs_start.set_int(101);
|
|
pk_objs_end.set_int(120);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(>, 'C2:110') || TableCompareFilter(!=, 'C3:')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%s,%s)\n", v1.get_int(), S(v2), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(15, result_cnt);
|
|
} // end case 15
|
|
{
|
|
// case 16 is/is_not comparator
|
|
fprintf(stderr, "case 16 is/is_not comparator\n");
|
|
// insert some data
|
|
for (int64_t i = 191; i <= 200; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar("hello world");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
}
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
fprintf(stderr, "case 16-1 filter_string=TableCompareFilter(IS, 'C3:')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(191);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(200);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(IS, 'C3:')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_TRUE(v3.is_null());
|
|
// fprintf(stderr, "(%ld,%ld)\n", v1.get_int(), v2.get_int());
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
fprintf(stderr, "case 16-2 filter_string=TableCompareFilter(IS_NOT, 'C3:')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
pk_objs_start.set_int(191);
|
|
pk_objs_end.set_int(200);
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(IS_NOT, 'C3:')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
result_cnt = 0;
|
|
while (OB_SUCC(iter->get_next_entity(result_entity))) {
|
|
result_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_TRUE(!v3.is_null());
|
|
// fprintf(stderr, "(%ld,%ld)\n", v1.get_int(), v2.get_int());
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(5, result_cnt);
|
|
} // end case 16
|
|
{
|
|
// case 17 query with filter and limit
|
|
fprintf(stderr, "case 17 query with filter and limit\n");
|
|
// insert some data
|
|
for (int64_t i = 201; i <= 210; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar("hello world");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
}
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
fprintf(stderr, "case 17-1 filter_string=TableCompareFilter(=, 'C3:hello world')\n");
|
|
query.reset();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ObObj pk_objs_start;
|
|
pk_objs_start.set_int(201);
|
|
ObObj pk_objs_end;
|
|
pk_objs_end.set_int(210);
|
|
ObNewRange range;
|
|
range.start_key_.assign(&pk_objs_start, 1);
|
|
range.end_key_.assign(&pk_objs_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_offset(1));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_limit(2));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello world')")));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
int expect_c1_values[] = {204, 206};
|
|
int expect_c2_values[] = {204, 206};
|
|
for (int i = 0; i < ARRAYSIZEOF(expect_c1_values); i++) {
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C1, v1));
|
|
ASSERT_EQ(v1.get_int(), expect_c1_values[i]);
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, v2));
|
|
ASSERT_EQ(v2.get_int(), expect_c2_values[i]);
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, v3));
|
|
ASSERT_EQ(v3.get_string(), "hello world");
|
|
// fprintf(stderr, "(%ld,%ld)\n", v1.get_int(), v2.get_int());
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
} // end case 17
|
|
// teardown
|
|
iter = nullptr;
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
|
|
// create table if not exists query_and_mutate (
|
|
// C1 bigint primary key,
|
|
// C2 bigint default null,
|
|
// C3 varchar(100) default null,
|
|
// C4 double default 0
|
|
// );
|
|
TEST_F(TestBatchExecute, table_query_and_mutate)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("query_and_mutate"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableOperationResult r;
|
|
ObITableEntity *entity = NULL;
|
|
const ObITableEntity *result_entity = NULL;
|
|
ObTableOperation table_operation;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObString s1 = ObString::make_string("hello c++");
|
|
ObString s2 = ObString::make_string("hello java");
|
|
ObString C4 = ObString::make_string("C4");
|
|
//prepare data
|
|
const int64_t batch_size = 100;
|
|
for (int64_t i = 1; i <= batch_size; ++i) {
|
|
entity->reset();
|
|
ObObj key, value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
value.set_double(1.0 * i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, value));
|
|
if (i % 2 == 0) {
|
|
value.set_varchar(s1);
|
|
} else {
|
|
value.set_varchar(s2);
|
|
}
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
table_operation = ObTableOperation::insert(*entity);
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute(table_operation, r));
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
ASSERT_EQ(ObTableOperationType::INSERT, r.type());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
}
|
|
the_table->set_entity_type(ObTableEntityType::ET_KV);
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
|
|
// case 1: simple mutate
|
|
{
|
|
ObObj pk_start, pk_end, value;
|
|
ObNewRange range;
|
|
ObTableQueryAndMutateResult result;
|
|
pk_start.set_int(10);
|
|
pk_end.set_int(15);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_int(666666);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
fprintf(stderr, "affect rows=%ld\n", result.affected_rows_);
|
|
ObTableQueryResult &query_result = result.affected_entity_;
|
|
const ObITableEntity *query_entity = NULL;
|
|
int64_t res_cnt = 0;
|
|
while (OB_SUCC(query_result.get_next_entity(query_entity))) {
|
|
res_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(res_cnt, result.affected_rows_);
|
|
}
|
|
// case 2: query empty
|
|
{
|
|
query.reset();
|
|
mutations.reset();
|
|
ObObj pk_start, pk_end, value;
|
|
ObNewRange range;
|
|
ObTableQueryAndMutateResult result;
|
|
pk_start.set_int(1000);
|
|
pk_end.set_int(2000);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_int(666666);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
ASSERT_EQ(0, result.affected_rows_);
|
|
}
|
|
// case 3: with filter query
|
|
{
|
|
// 3-1 TableCompareFilter(=, 'C2:20')
|
|
query.reset();
|
|
mutations.reset();
|
|
ObObj pk_start, pk_end, value;
|
|
ObNewRange range;
|
|
ObTableQueryAndMutateResult result;
|
|
pk_start.set_int(16);
|
|
pk_end.set_int(20);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C2:18')")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_int(55555);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
ASSERT_GT(result.affected_rows_, 0);
|
|
fprintf(stderr, "3-1 affect rows=%ld\n", result.affected_rows_);
|
|
ObTableQueryResult &query_result = result.affected_entity_;
|
|
const ObITableEntity *query_entity = NULL;
|
|
int64_t res_cnt = 0;
|
|
while (OB_SUCC(query_result.get_next_entity(query_entity))) {
|
|
res_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(res_cnt, result.affected_rows_);
|
|
// 3-2 filter_string=TableCompareFilter(=, 'C3:hello c++') && TableCompareFilter(>, 'C2:24')
|
|
query.reset();
|
|
mutations.reset();
|
|
pk_start.reset();
|
|
pk_end.reset();
|
|
value.reset();
|
|
range.reset();
|
|
entity->reset();
|
|
res_cnt = 0;
|
|
ret = OB_SUCCESS;
|
|
|
|
pk_start.set_int(21);
|
|
pk_end.set_int(30);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello c++') && TableCompareFilter(>, 'C2:24')")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_varchar("hello c++++");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
ASSERT_GT(result.affected_rows_, 0);
|
|
fprintf(stderr, "3-2 affect rows=%ld\n", result.affected_rows_);
|
|
while (OB_SUCC(query_result.get_next_entity(query_entity))) {
|
|
res_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(res_cnt, result.affected_rows_);
|
|
// 3-3 filter_string=TableCompareFilter(<, 'C2:25') || TableCompareFilter(>, 'C2:35')
|
|
query.reset();
|
|
mutations.reset();
|
|
pk_start.reset();
|
|
pk_end.reset();
|
|
value.reset();
|
|
range.reset();
|
|
entity->reset();
|
|
res_cnt = 0;
|
|
ret = OB_SUCCESS;
|
|
pk_start.set_int(21);
|
|
pk_end.set_int(40);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(<, 'C2:25') || TableCompareFilter(>, 'C2:35')")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_varchar("big wish");
|
|
value.set_collation_type(CS_TYPE_UTF8MB4_BIN);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
ASSERT_GT(result.affected_rows_, 0);
|
|
fprintf(stderr, "3-3 affect rows=%ld\n", result.affected_rows_);
|
|
while (OB_SUCC(query_result.get_next_entity(query_entity))) {
|
|
res_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(res_cnt, result.affected_rows_);
|
|
}
|
|
// case 4: incrment, append, delete
|
|
{
|
|
// 4-1 increment
|
|
query.reset();
|
|
mutations.reset();
|
|
ObObj pk_start, pk_end, value;
|
|
ObNewRange range;
|
|
ObTableQueryAndMutateResult result;
|
|
pk_start.set_int(41);
|
|
pk_end.set_int(50);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C2:48')")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
value.set_int(1000);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.increment(*entity));
|
|
ObTableQueryResult &query_result = result.affected_entity_;
|
|
const ObITableEntity *query_entity = NULL;
|
|
int64_t res_cnt = 0;
|
|
// 4-3 delete
|
|
query.reset();
|
|
mutations.reset();
|
|
pk_start.reset();
|
|
pk_end.reset();
|
|
value.reset();
|
|
range.reset();
|
|
entity->reset();
|
|
res_cnt = 0;
|
|
ret = OB_SUCCESS;
|
|
|
|
pk_start.set_int(61);
|
|
pk_end.set_int(70);
|
|
range.start_key_.assign(&pk_start, 1);
|
|
range.end_key_.assign(&pk_end, 1);
|
|
range.border_flag_.set_inclusive_start();
|
|
range.border_flag_.set_inclusive_end();
|
|
ASSERT_EQ(OB_SUCCESS, query.add_scan_range(range));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C1));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C2));
|
|
ASSERT_EQ(OB_SUCCESS, query.add_select_column(C3));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_scan_index(ObString::make_string("primary")));
|
|
ASSERT_EQ(OB_SUCCESS, query.set_filter(ObString::make_string("TableCompareFilter(=, 'C3:hello c++') && TableCompareFilter(>, 'C2:24')")));
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, mutations.del(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
ASSERT_GT(result.affected_rows_, 0);
|
|
fprintf(stderr, "4-3 affect rows=%ld\n", result.affected_rows_);
|
|
while (OB_SUCC(query_result.get_next_entity(query_entity))) {
|
|
res_cnt++;
|
|
ObObj v1, v2, v3;
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C1, v1));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C2, v2));
|
|
ASSERT_EQ(OB_SUCCESS, query_entity->get_property(C3, v3));
|
|
// fprintf(stderr, "(%ld,%ld,%s)\n", v1.get_int(), v2.get_int(), S(v3));
|
|
}
|
|
ASSERT_EQ(OB_ITER_END, ret);
|
|
ASSERT_EQ(res_cnt, result.affected_rows_);
|
|
// 4-4 batch
|
|
}
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
/*
|
|
* CREATE TABLE atomic_batch_ops (
|
|
* c1 bigint not null,
|
|
* c2 varchar(128) not null,
|
|
* c3 varbinary(1024) default null,
|
|
* c4 int not null default -1,
|
|
* primary key(c1),
|
|
* UNIQUE KEY idx_c2c4 (`c2`, `c4`)
|
|
* )
|
|
*/
|
|
TEST_F(TestBatchExecute, atomic_batch_ops)
|
|
{
|
|
ObTable *table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("atomic_batch_ops"), table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperationResult result;
|
|
ObITableEntity *entity = NULL;
|
|
ObTableBatchOperation table_batch_operation;
|
|
ObTableRequestOptions req_options;
|
|
|
|
// ObString C1 = ObString::make_string("C1");
|
|
ObString C2 = ObString::make_string("C2");
|
|
ObString C3 = ObString::make_string("C3");
|
|
ObString C4 = ObString::make_string("C4");
|
|
|
|
// set atomic batch false
|
|
req_options.set_batch_operation_as_atomic(false);
|
|
req_options.set_returning_affected_rows(true);
|
|
|
|
// multi insert
|
|
// CRITICAL ERROR
|
|
// +----+-------+-------+----+
|
|
// | C1 | c2 | c3 | c4 |
|
|
// +----+-------+-------+----+
|
|
// | 5 | hello | world | 1 |
|
|
// | 6 | hello | world | 1 |
|
|
// +----+-------+-------+----+
|
|
{
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
|
|
ObObj key, c2_value, c3_value, c4_value;
|
|
|
|
key.set_int(5);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(1);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
// duplicate uk insert
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
key.set_int(6);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(2, result.count());
|
|
for (int64_t i = 0; i < result.count(); i++) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
if (0 == i) {
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
} else {
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, r.get_errno());
|
|
}
|
|
}
|
|
|
|
// multi get
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 5; i <= 6; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.retrieve(*entity));
|
|
}
|
|
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(2, result.count());
|
|
for (int64_t i = 0; i < result.count(); ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
|
|
ObObj c2_obj, c3_obj, c4_obj;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, c3_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, c4_obj));
|
|
|
|
ObObj val2, val3, val4;
|
|
val2.set_varchar(ObString::make_string("hello"));
|
|
val2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
val3.set_varbinary(ObString::make_string("world"));
|
|
val4.set_int(1);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
}
|
|
}
|
|
|
|
// multi delete
|
|
{
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 5; i <= 6; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
// 当前的数据
|
|
// +----+-------+------------------+----+
|
|
// | c1 | c2 | cast(c3 as char) | c4 |
|
|
// +----+-------+------------------+----+
|
|
// | 5 | hello | world | 1 |
|
|
// | 6 | hello | world | 1 |
|
|
// +----+-------+------------------+----+
|
|
// 删唯一索引的时候会报错4377,因为c2,c4联合唯一索引有两条一模一样的数据,第二次删除会找不到记录,第一次已经删完。
|
|
ASSERT_EQ(OB_ERR_DEFENSIVE_CHECK, table->batch_execute(table_batch_operation, req_options, result));
|
|
}
|
|
|
|
// delete again
|
|
{
|
|
entity->reset();
|
|
ObObj key;
|
|
key.set_int(5);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::del(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_SUCCESS, table->execute(table_operation, r));
|
|
|
|
entity->reset();
|
|
key.set_int(6);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
table_operation = ObTableOperation::del(*entity);
|
|
// 第二条还是删不掉,遗留成为脏数据
|
|
// +----+-------+------------------+----+
|
|
// | c1 | c2 | cast(c3 as char) | c4 |
|
|
// +----+-------+------------------+----+
|
|
// | 6 | hello | world | 1 |
|
|
// +----+-------+------------------+----+
|
|
ASSERT_EQ(OB_ERR_DEFENSIVE_CHECK, table->execute(table_operation, r));
|
|
}
|
|
|
|
// multi_insert
|
|
// +----+-------+-------+----+
|
|
// | C1 | c2 | c3 | c4 |
|
|
// +----+-------+-------+----+
|
|
// | 1 | hello | world | 1 |
|
|
// | 2 | hello | world | 2 |
|
|
// +----+-------+-------+----+
|
|
{
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int i = 1; i < 3; i++) {
|
|
entity = entity_factory.alloc();
|
|
|
|
ObObj key, c2_value, c3_value, c4_value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(2, result.count());
|
|
for (int64_t i = 0; i < result.count(); i++) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(1, r.get_affected_rows());
|
|
}
|
|
}
|
|
|
|
// multi_update
|
|
// CRITICAL ERROR
|
|
// +----+-------+------------------+----+
|
|
// | c1 | c2 | cast(c3 as char) | c4 |
|
|
// +----+-------+------------------+----+
|
|
// | 1 | hello | world | 1 |
|
|
// | 2 | hello | world | 1 |
|
|
// | 6 | hello | world | 1 |
|
|
// +----+-------+------------------+----+
|
|
{
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c4_val;
|
|
key.set_int(2);
|
|
c4_val.set_int(1);
|
|
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_val));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.update(*entity));
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(1, result.count());
|
|
for (int64_t i = 0; i < result.count(); i++) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, r.get_errno());
|
|
}
|
|
}
|
|
|
|
// reset data
|
|
// +----+-------+-------+----+
|
|
// | C1 | c2 | c3 | c4 |
|
|
// +----+-------+-------+----+
|
|
// | 1 | hello | world | 1 |
|
|
// | 2 | hello | world | 2 |
|
|
// +----+-------+-------+----+
|
|
{
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 1; i <= 2; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
|
|
for (int i = 1; i <= 2; i++) {
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c2_value, c3_value, c4_value;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
}
|
|
|
|
ASSERT_EQ(OB_ERR_DEFENSIVE_CHECK, table->batch_execute(table_batch_operation, req_options, result));
|
|
}
|
|
|
|
// set atomic batch true
|
|
req_options.set_batch_operation_as_atomic(true);
|
|
|
|
// current
|
|
// +----+-------+------------------+----+
|
|
// | c1 | c2 | cast(c3 as char) | c4 |
|
|
// +----+-------+------------------+----+
|
|
// | 1 | hello | world | 1 |
|
|
// | 2 | hello | world | 1 |
|
|
// | 6 | hello | world | 1 |
|
|
// +----+-------+------------------+----+
|
|
|
|
// multi insert
|
|
{
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
c4_value.set_int(1);
|
|
for (int64_t i = 11; i < 13; i++) {
|
|
entity = entity_factory.alloc();
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(0, result.count());
|
|
|
|
// get
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 11; i <= 12; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.retrieve(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(2, result.count());
|
|
for (int64_t i = 0; i < result.count(); i++) {
|
|
ObTableOperationResult &r = result.at(i);
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ObITableEntity *result_entity;
|
|
ASSERT_TRUE(OB_SUCC(r.get_entity(result_entity)));
|
|
ASSERT_TRUE(result_entity->is_empty());
|
|
}
|
|
}
|
|
|
|
// multi update
|
|
{
|
|
// prepare data
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
for (int64_t i = 11; i < 13; i++) {
|
|
entity = entity_factory.alloc();
|
|
key.set_int(i);
|
|
c4_value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(2, result.count());
|
|
|
|
// update
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
c4_value.set_int(11);
|
|
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.update(*entity));
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
for (int i = 0; i < result.count(); i++) {
|
|
ObTableOperationResult &r = result.at(i);
|
|
ObITableEntity *result_entity;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
fprintf(stderr, "errno: %d, is empty: %d, type: %d\n", r.get_errno(), result_entity->is_empty(), r.type());
|
|
}
|
|
ASSERT_EQ(0, result.count());
|
|
}
|
|
|
|
// multi insert_or_update
|
|
{
|
|
// clear
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 11; i < 13; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
key.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert_or_update(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c4_value.set_int(13);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert_or_update(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert_or_update(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert_or_update(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(14);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert_or_update(*entity));
|
|
|
|
// ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(0, result.count());
|
|
}
|
|
|
|
// multi append
|
|
{
|
|
// clear
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 11; i <= 14; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
|
|
// prepare
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
key.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
c2_value.set_varchar(ObString::make_string("he"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c2_value.set_varchar(ObString::make_string("hell"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(3, result.count());
|
|
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
c2_value.set_varchar(ObString::make_string("llo"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.append(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c2_value.set_varchar(ObString::make_string("o"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.append(*entity));
|
|
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(0, result.count());
|
|
|
|
// get
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 11; i <= 13; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.retrieve(*entity));
|
|
}
|
|
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(3, result.count());
|
|
for (int64_t i = 0; i < result.count(); ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
|
|
ObObj c2_obj, c3_obj, c4_obj;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, c3_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, c4_obj));
|
|
|
|
ObObj val2, val3, val4;
|
|
val3.set_varbinary(ObString::make_string("world"));
|
|
val4.set_int(11);
|
|
switch (i) {
|
|
case 10: {
|
|
val2.set_varchar(ObString::make_string("hello"));
|
|
val2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
|
|
case 11: {
|
|
val2.set_varchar(ObString::make_string("he"));
|
|
val2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
|
|
case 12: {
|
|
val2.set_varchar(ObString::make_string("hell"));
|
|
val2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// multi increment
|
|
{
|
|
// clear
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 11; i <= 14; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
|
|
// prepare
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
key.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
c4_value.set_int(12);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c4_value.set_int(13);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
key.set_int(12);
|
|
c4_value.set_int(19);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.increment(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c4_value.set_int(18);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.increment(*entity));
|
|
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(0, result.count());
|
|
|
|
// get
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
ObObj null_obj;
|
|
for (int64_t i = 11; i <= 13; ++i) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, null_obj));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.retrieve(*entity));
|
|
}
|
|
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(3, result.count());
|
|
for (int64_t i = 0; i < result.count(); ++i) {
|
|
const ObTableOperationResult &r = result.at(i);
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, r.get_errno());
|
|
ASSERT_EQ(ObTableOperationType::GET, r.type());
|
|
ASSERT_EQ(0, r.get_affected_rows());
|
|
ASSERT_EQ(OB_SUCCESS, r.get_entity(result_entity));
|
|
ASSERT_TRUE(NULL != result_entity);
|
|
ASSERT_EQ(0, result_entity->get_rowkey_size());
|
|
|
|
ObObj c2_obj, c3_obj, c4_obj;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C2, c2_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C3, c3_obj));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(C4, c4_obj));
|
|
|
|
ObObj val2, val3, val4;
|
|
val2.set_varchar(ObString::make_string("hello"));
|
|
val2.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
val3.set_varbinary(ObString::make_string("world"));
|
|
switch (i) {
|
|
case 10: {
|
|
val4.set_int(11);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
|
|
case 11: {
|
|
val4.set_int(2);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
|
|
case 12: {
|
|
val4.set_int(3);
|
|
ASSERT_EQ(val2, c2_obj);
|
|
ASSERT_EQ(val3, c3_obj);
|
|
ASSERT_EQ(val4, c4_obj);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// batch
|
|
{
|
|
// clear
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
for (int64_t i = 11; i <= 14; i++) {
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
key.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.del(*entity));
|
|
}
|
|
ASSERT_EQ(OB_SUCCESS, table->batch_execute(table_batch_operation, req_options, result));
|
|
|
|
table_batch_operation.reset();
|
|
entity_factory.free_and_reuse();
|
|
result.reuse();
|
|
entity = entity_factory.alloc();
|
|
ObObj key, c1_value, c2_value, c3_value, c4_value;
|
|
key.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
c2_value.set_varchar(ObString::make_string("hello"));
|
|
c2_value.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
c3_value.set_varbinary(ObString::make_string("world"));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
// entity = entity_factory.alloc();
|
|
// key.set_int(2);
|
|
// ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
// ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
// ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
|
|
for (int64_t i = 13; i <= 15; i++) {
|
|
entity = entity_factory.alloc();
|
|
key.set_int(i);
|
|
c4_value.set_int(i);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C2, c2_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C3, c3_value));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.insert(*entity));
|
|
}
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(13);
|
|
c4_value.set_int(12);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.increment(*entity));
|
|
|
|
entity = entity_factory.alloc();
|
|
key.set_int(14);
|
|
c4_value.set_int(11);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(C4, c4_value));
|
|
ASSERT_EQ(OB_SUCCESS, table_batch_operation.increment(*entity));
|
|
|
|
ASSERT_EQ(OB_ERR_PRIMARY_KEY_DUPLICATE, table->batch_execute(table_batch_operation, req_options, result));
|
|
ASSERT_EQ(0, result.count());
|
|
}
|
|
|
|
service_client_->free_table(table);
|
|
table = NULL;
|
|
}
|
|
// create table if not exists auto_increment_defensive_test
|
|
// (C1 bigint AUTO_INCREMENT primary key) PARTITION BY KEY(C1) PARTITIONS 16;
|
|
TEST_F(TestBatchExecute, auto_increment_auto_increment_defensive)
|
|
{
|
|
OB_LOG(INFO, "begin single_insert");
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("auto_increment_defensive_test"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObITableEntity *entity = NULL;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ObObj key;
|
|
int key_key = 1234;
|
|
key.set_int(key_key);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key));
|
|
ObTableOperation table_operation = ObTableOperation::insert(*entity);
|
|
ObTableOperationResult r;
|
|
ASSERT_EQ(OB_NOT_SUPPORTED, the_table->execute(table_operation, r));
|
|
}
|
|
// create table if not exists htable1_cf1_check_and_delete(K varbinary(1024), Q varbinary(256), T bigint, V varbinary(1024), K_PREFIX varbinary(1024) GENERATED ALWAYS AS (substr(K,1,32)) STORED, primary key(K, Q, T));" $db
|
|
TEST_F(TestBatchExecute, htable_check_and_put)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_check_and_put"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const char* rowkey = "row1";
|
|
const char *qualifier = "cq1";
|
|
// set query of checkAndPut
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
ObObj key1, key2, key3, value;
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
// check with value is null three times
|
|
// put1: row1, cq1, "", check success
|
|
// put2: row1, cq1, "string100", check success
|
|
// put3: row1, cq1, "string101", check failed
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
htable_filter.set_filter(ObString::make_string("CheckAndMutateFilter(=, 'binary:', 'cf1', 'cq1', true)"));
|
|
htable_filter.set_valid(true);
|
|
const char *values[3] = {"", "string100", "string200"};
|
|
for (int i = 0; i < 3; i++) {
|
|
mutations.reset();
|
|
entity->reset();
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
key2.set_varbinary(ObString::make_string(qualifier));
|
|
key3.set_int(INT64_MAX);
|
|
value.set_varbinary(ObString::make_string(values[i]));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.insert_or_update(*entity));
|
|
ObTableQueryAndMutateResult result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query_and_mutate(query_and_mutate, result));
|
|
if (i < 2) {
|
|
ASSERT_EQ(1, result.affected_rows_);
|
|
} else {
|
|
ASSERT_EQ(0, result.affected_rows_);
|
|
}
|
|
}
|
|
// unstable test cases
|
|
// execute query and verify result
|
|
// htable_filter.reset();
|
|
// htable_filter.add_column(ObString::make_string(qualifier));
|
|
// htable_filter.set_max_versions(INT32_MAX); // get all versions
|
|
// htable_filter.set_valid(true);
|
|
// ObTableEntityIterator *iter = nullptr;
|
|
// ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
// const ObITableEntity *result_entity = NULL;
|
|
// ObObj rk, cq, ts, val;
|
|
// ObString str;
|
|
// for (int j = 0; j < 2; j++) {
|
|
// ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
// ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
// ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
// ASSERT_EQ(key1, rk);
|
|
// ASSERT_EQ(key2, cq);
|
|
// ASSERT_TRUE(str.compare(values[1-j]) == 0);
|
|
// }
|
|
// ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
TEST_F(TestBatchExecute, htable_check_and_put_multi_thread)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_check_and_put"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const char* rowkey = "row2";
|
|
const char *qualifier = "cq2";
|
|
ObString val_str = "string0";
|
|
// set query of checkAndPut
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
htable_filter.set_filter(ObString::make_string("CheckAndMutateFilter(=, 'substring:string0', 'cf1', 'cq2', true)"));
|
|
htable_filter.set_valid(true);
|
|
// set put mutation
|
|
mutations.reset();
|
|
ObObj key1, key2, key3, value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
key2.set_varbinary(ObString::make_string(qualifier));
|
|
key3.set_int(INT64_MAX);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(val_str);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.insert_or_update(*entity));
|
|
int64_t total_affected_rows = 0;
|
|
// 3. execute checkAndPut concurently with value is null
|
|
auto task = [&](ObTable* one_table, const ObTableQueryAndMutate &query_and_mutate) {
|
|
ObTableQueryAndMutateResult inc_result;
|
|
ASSERT_EQ(OB_SUCCESS, one_table->execute_query_and_mutate(query_and_mutate, inc_result));
|
|
(void)ATOMIC_AAF(&total_affected_rows, inc_result.affected_rows_);
|
|
};
|
|
constexpr uint64_t thread_num = 100;
|
|
std::vector<std::thread> threads;
|
|
time_t start_time = time(NULL);
|
|
printf("begin to run tasks, thread_num: %ld\n", thread_num);
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
std::thread t(task, the_table, query_and_mutate);
|
|
threads.push_back(std::move(t));
|
|
}
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
threads.at(i).join();
|
|
}
|
|
printf("time elapsed during checkAndPut process: %lfs\n", double(time(NULL) - start_time));
|
|
|
|
// 4. execute query and verify result
|
|
htable_filter.reset();
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
htable_filter.set_max_versions(INT32_MAX); // get all versions
|
|
htable_filter.set_valid(true);
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(str, val_str);
|
|
ASSERT_EQ(1, ATOMIC_LOAD(&total_affected_rows));
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
// execute multiply checkAndPut(with check null and put empty) and one put(with value is not empty) operation
|
|
// concurrently, the newest cell value should generated by the put opreation
|
|
TEST_F(TestBatchExecute, htable_check_and_put_put)
|
|
{
|
|
// setup
|
|
ObTable *the_table = NULL;
|
|
int ret = service_client_->alloc_table(ObString::make_string("htable1_cf1_check_and_put_put"), the_table);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
the_table->set_entity_type(ObTableEntityType::ET_HKV); // important
|
|
ObTableEntityFactory<ObTableEntity> entity_factory;
|
|
ObTableBatchOperation batch_operation;
|
|
ObITableEntity *entity = NULL;
|
|
const char* rowkey = "row2";
|
|
const char *qualifier = "cq2";
|
|
const char* null_val = "";
|
|
// set query of checkAndPut
|
|
ObTableQueryAndMutate query_and_mutate;
|
|
ObTableQuery &query = query_and_mutate.get_query();
|
|
ObTableBatchOperation &mutations = query_and_mutate.get_mutations();
|
|
ObObj pk_objs_start[3];
|
|
ObObj pk_objs_end[3];
|
|
ASSERT_NO_FATAL_FAILURE(generate_get(query, pk_objs_start, pk_objs_end, rowkey));
|
|
ObHTableFilter &htable_filter = query.htable_filter();
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
htable_filter.set_filter(ObString::make_string("CheckAndMutateFilter(=, 'substring:string0', 'cf1', 'cq2', true)"));
|
|
htable_filter.set_valid(true);
|
|
// set put mutation
|
|
mutations.reset();
|
|
ObObj key1, key2, key3, value;
|
|
key1.set_varbinary(ObString::make_string(rowkey));
|
|
key2.set_varbinary(ObString::make_string(qualifier));
|
|
key3.set_int(INT64_MAX);
|
|
entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != entity);
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, entity->add_rowkey_value(key3));
|
|
value.set_varbinary(null_val);
|
|
ASSERT_EQ(OB_SUCCESS, entity->set_property(V, value));
|
|
ASSERT_EQ(OB_SUCCESS, mutations.insert_or_update(*entity));
|
|
// set htable put operation with value is not null
|
|
ObTableBatchOperation put_op;
|
|
ObString put_val_str = "hello world";
|
|
ObObj put_value;
|
|
ObITableEntity *put_entity = entity_factory.alloc();
|
|
ASSERT_TRUE(NULL != put_entity);
|
|
ASSERT_EQ(OB_SUCCESS, put_entity->add_rowkey_value(key1));
|
|
ASSERT_EQ(OB_SUCCESS, put_entity->add_rowkey_value(key2));
|
|
ASSERT_EQ(OB_SUCCESS, put_entity->add_rowkey_value(key3));
|
|
put_value.set_varbinary(put_val_str);
|
|
ASSERT_EQ(OB_SUCCESS, put_entity->set_property(V, put_value));
|
|
ASSERT_EQ(OB_SUCCESS, put_op.insert_or_update(*put_entity));
|
|
// 3. execute checkAndPut concurently with check value is null and put value is null
|
|
auto check_and_put_task = [&](ObTable* one_table, const ObTableQueryAndMutate &query_and_mutate) {
|
|
ObTableQueryAndMutateResult inc_result;
|
|
int one_ret = one_table->execute_query_and_mutate(query_and_mutate, inc_result);
|
|
ASSERT_TRUE(one_ret == OB_SUCCESS || one_ret == OB_TRY_LOCK_ROW_CONFLICT);
|
|
};
|
|
auto put_task = [&]() {
|
|
ObTableBatchOperationResult put_result;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->batch_execute(put_op, put_result));
|
|
ASSERT_EQ(1, put_result.count());
|
|
};
|
|
std::thread put_t(put_task);
|
|
constexpr uint64_t thread_num = 200;
|
|
std::vector<std::thread> threads;
|
|
time_t start_time = time(NULL);
|
|
printf("begin to run tasks, thread_num: %ld\n", thread_num);
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
std::thread t(check_and_put_task, the_table, query_and_mutate);
|
|
threads.push_back(std::move(t));
|
|
}
|
|
put_t.join();
|
|
for (uint64_t i = 0; i < thread_num; ++i) {
|
|
threads.at(i).join();
|
|
}
|
|
printf("time elapsed during checkAndPut process: %lfs\n", double(time(NULL) - start_time));
|
|
|
|
// 4. execute query and verify result
|
|
htable_filter.reset();
|
|
htable_filter.add_column(ObString::make_string(qualifier));
|
|
htable_filter.set_max_versions(1); // get all versions
|
|
htable_filter.set_valid(true);
|
|
ObTableEntityIterator *iter = nullptr;
|
|
ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter));
|
|
const ObITableEntity *result_entity = NULL;
|
|
ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity));
|
|
ObObj rk, cq, ts, val;
|
|
ObString str;
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts));
|
|
ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val));
|
|
ASSERT_EQ(OB_SUCCESS, val.get_varbinary(str));
|
|
ASSERT_EQ(key1, rk);
|
|
ASSERT_EQ(key2, cq);
|
|
ASSERT_EQ(str, put_val_str);
|
|
ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity));
|
|
////////////////////////////////////////////////////////////////
|
|
// teardown
|
|
service_client_->free_table(the_table);
|
|
the_table = NULL;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
::testing::InitGoogleTest(&argc,argv);
|
|
if (argc == 9)
|
|
{
|
|
host = argv[1];
|
|
sql_port = atoi(argv[2]);
|
|
tenant = argv[3];
|
|
user_name = argv[4];
|
|
passwd = argv[5];
|
|
db = argv[6];
|
|
table_name = argv[7];
|
|
rpc_port = atoi(argv[8]);
|
|
}
|
|
ObTableServiceLibrary::init();
|
|
int ret = RUN_ALL_TESTS();
|
|
ObTableServiceLibrary::destroy();
|
|
return ret;
|
|
}
|