init push

This commit is contained in:
oceanbase-admin
2021-05-31 22:56:52 +08:00
commit cea7de1475
7020 changed files with 5689869 additions and 0 deletions

View File

@ -0,0 +1,9 @@
function(join_unittest case)
ob_unittest(${ARGV})
target_sources(${case} PRIVATE ob_join_fake_table.h ob_join_fake_table.cpp)
endfunction()
join_unittest(ob_merge_join_test)
#join_unittest(ob_nested_loop_join_test)
join_unittest(ob_hash_join_test)
ob_unittest(farm_tmp_disabled_test_hash_join_dump test_hash_join_dump.cpp join_data_generator.h)

View File

@ -0,0 +1,197 @@
/**
* 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.
*/
#ifndef OCEANBASE_JOIN_JOIN_DATA_GENERATOR_H_
#define OCEANBASE_JOIN_JOIN_DATA_GENERATOR_H_
#include <functional>
#include "sql/engine/ob_phy_operator.h"
#include "sql/engine/ob_exec_context.h"
namespace oceanbase {
namespace sql {
class JoinDataGenerator : public ObPhyOperator {
public:
const static int64_t CELL_CNT = 4;
const static int64_t ROW_ID_CELL = 0;
const static int64_t IDX_CELL = 1;
const static int64_t RAND_CELL = 2;
const static int64_t STR_CELL = 3;
const static int64_t INT_VARCHAR_BUF_SIZE = 10;
class Ctx : public ObPhyOperatorCtx {
public:
Ctx(ObExecContext& c) : ObPhyOperatorCtx(c)
{}
virtual void destroy()
{
return ObPhyOperatorCtx::destroy_base();
}
};
explicit JoinDataGenerator(common::ObIAllocator& alloc) : ObPhyOperator(alloc)
{
type_ = PHY_TABLE_SCAN;
}
virtual int set_child(int32_t, ObPhyOperator&)
{
return common::OB_SUCCESS;
}
virtual ObPhyOperator* get_child(int32_t) const
{
return NULL;
}
virtual int32_t get_child_num() const
{
return 0;
}
virtual int inner_get_next_row(ObExecContext&, const common::ObNewRow*&) const
{
return common::OB_SUCCESS;
}
int close(ObExecContext&) const
{
return common::OB_SUCCESS;
}
~JoinDataGenerator()
{
if (str_) {
delete[] str_;
str_ = NULL;
}
if (projector_) {
delete[] projector_;
projector_ = NULL;
}
}
// row_cnt_ idx_cnt_func_ must set before init
int test_init()
{
int ret = OB_SUCCESS;
if (NULL == projector_) {
projector_ = new int32_t[CELL_CNT];
projector_size_ = CELL_CNT;
for (int i = 0; i < CELL_CNT; i++) {
projector_[i] = i;
}
}
set_column_count(CELL_CNT);
row_id_ = 0;
if (reverse_) {
row_id_ = row_cnt_ - 1;
}
str_ = new char[string_size_];
memset(str_, 'x', string_size_);
row_.cells_ = cells_;
row_.count_ = CELL_CNT;
row_.projector_size_ = projector_size_;
row_.projector_ = projector_;
return ret;
}
virtual int init_op_ctx(ObExecContext& ec) const override
{
Ctx* ctx = NULL;
return CREATE_PHY_OPERATOR_CTX(Ctx, ec, get_id(), get_type(), ctx);
}
virtual int inner_open(ObExecContext& ec) const override
{
return init_op_ctx(ec);
}
void next_row_id() const
{
row_id_ += !reverse_ ? 1 : -1;
idx_ = 0;
idx_cnt_ = 0;
}
virtual int get_next_row(ObExecContext&, const common::ObNewRow*& row) const override
{
while (true) {
if (row_id_ < 0 || row_id_ >= row_cnt_) {
row = NULL;
return iter_end_ret_;
}
if (idx_cnt_ == 0) {
idx_cnt_ = idx_cnt_func_(row_id_, row_cnt_);
}
if (idx_ < idx_cnt_) {
construct_row();
row = &row_;
idx_++;
return OB_SUCCESS;
}
if (idx_ >= idx_cnt_) {
next_row_id();
}
}
return OB_SUCCESS;
}
void construct_row() const
{
int64_t rand = murmurhash64A(&row_id_, sizeof(row_id_), 0);
rand = murmurhash64A(&idx_, sizeof(idx_), (uint64_t)rand);
ObObj* objs[] = {&cells_[ROW_ID_CELL], &cells_[IDX_CELL], &cells_[RAND_CELL]};
int64_t ints[] = {row_id_val_(row_id_), idx_val_(idx_), rand};
if (!gen_varchar_cell_) {
for (int64_t i = 0; i < ARRAYSIZEOF(objs); i++) {
objs[i]->set_int(ints[i]);
}
} else {
char* bufs[] = {&int_varchar_buf_[ROW_ID_CELL * INT_VARCHAR_BUF_SIZE],
&int_varchar_buf_[IDX_CELL * INT_VARCHAR_BUF_SIZE],
&int_varchar_buf_[RAND_CELL * INT_VARCHAR_BUF_SIZE]};
for (int64_t i = 0; i < ARRAYSIZEOF(objs); i++) {
snprintf(bufs[i], INT_VARCHAR_BUF_SIZE, "%0.*ld", (int)INT_VARCHAR_BUF_SIZE, ints[i]);
objs[i]->set_varchar(bufs[i], INT_VARCHAR_BUF_SIZE);
}
}
cells_[STR_CELL].set_varchar(str_, string_size_);
}
public:
bool gen_varchar_cell_ = false;
int64_t row_cnt_ = 1;
bool reverse_ = false;
int string_size_ = 64;
typedef std::function<int64_t(const int64_t, const int64_t)> IdxCntFunc;
IdxCntFunc idx_cnt_func_ = [](const int64_t, const int64_t) { return 1; };
typedef std::function<int64_t(const int64_t)> IdValFunc;
IdValFunc row_id_val_ = [](const int64_t v) { return v; };
IdValFunc idx_val_ = [](const int64_t v) { return v; };
int iter_end_ret_ = OB_ITER_END;
private:
mutable common::ObNewRow row_;
mutable common::ObObj cells_[CELL_CNT];
mutable int64_t row_id_ = 0;
mutable int64_t idx_ = 0;
mutable int64_t idx_cnt_ = 0;
mutable char* str_ = NULL;
mutable char int_varchar_buf_[CELL_CNT * INT_VARCHAR_BUF_SIZE];
};
} // namespace sql
} // namespace oceanbase
#endif // OCEANBASE_JOIN_JOIN_DATA_GENERATOR_H_

View File

@ -0,0 +1,486 @@
/**
* 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>
#define private public
#define protected public
#include "lib/utility/ob_test_util.h"
#include "sql/engine/join/ob_hash_join.h"
#include "ob_join_fake_table.h"
#include "sql/engine/expr/ob_expr_equal.h"
#include "sql/engine/expr/ob_expr_mod.h"
#include "sql/ob_sql_init.h"
#include "sql/session/ob_sql_session_info.h"
#include "lib/utility/ob_tracepoint.h"
#include "observer/ob_server.h"
#include "observer/ob_server_struct.h"
#include "share/ob_tenant_mgr.h"
#include <vector>
#include "sql/engine/test_engine_util.h"
using namespace oceanbase::sql;
using namespace oceanbase::sql::test;
using namespace oceanbase::common;
using namespace oceanbase::observer;
using namespace oceanbase::share;
class MockSqlExpression : public ObSqlExpression {
public:
MockSqlExpression() : ObSqlExpression(alloc_)
{
set_item_count(10);
}
~MockSqlExpression()
{}
};
class ObHashJoinTest : public ::testing::Test {
public:
ObHashJoinTest();
virtual ~ObHashJoinTest();
protected:
void join_test(int64_t case_id, ObJoinType join_type);
void serialize_test();
void join_exception_test(int expect_ret);
void serialize_exception_test(int expect_ret);
void memlimit_exception_test(int expect_ret, int64_t mem_size);
// disallow copy
ObHashJoinTest(const ObHashJoinTest& other);
ObHashJoinTest& operator=(const ObHashJoinTest& other);
private:
// data members
};
class ObHashJoinPlan {
public:
static ObHashJoin& get_instance()
{
return hash_join_;
}
static ObJoinFakeTable& get_out_data()
{
return out_data_;
}
static ObPhysicalPlan* get_phy_plan()
{
return &phy_plan_;
}
static int init(int64_t case_id, ObJoinType join_type)
{
int ret = OB_SUCCESS;
if (OB_FAIL(left_op_.init(HASH_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "left op init failed", K(ret));
} else if (OB_FAIL(right_op_.init(HASH_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "right op init failed", K(ret));
} else if (OB_FAIL(out_data_.init(HASH_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "out data init failed", K(ret));
} else {
hash_join_.set_phy_plan(&phy_plan_);
left_op_.set_phy_plan(&phy_plan_);
right_op_.set_phy_plan(&phy_plan_);
left_op_.set_rows(10000); // default
out_data_.set_phy_plan(&phy_plan_);
set_id();
set_column_count(2);
projector_[0] = 0;
projector_[1] = 1;
projector_size_ = 2;
left_op_.set_projector(projector_, projector_size_);
right_op_.set_projector(projector_, projector_size_);
if (OB_FAIL(hash_join_.set_child(0, left_op_))) {
} else if (OB_FAIL(hash_join_.set_child(1, right_op_))) {
} else if (OB_FAIL(hash_join_.set_join_type(join_type))) {
} else if (OB_FAIL(hash_join_.set_join_type(join_type))) {
} else if (OB_FAIL(init_equal_conds())) {
} else if (OB_FAIL(init_other_conds())) {
} else if (OB_FAIL(left_op_.prepare_data(case_id, TT_LEFT_TABLE, join_type))) {
} else if (OB_FAIL(right_op_.prepare_data(case_id, TT_RIGHT_TABLE, join_type))) {
} else if (OB_FAIL(out_data_.prepare_data(case_id, TT_OUT_TABLE, join_type))) {
}
}
return ret;
}
static void reuse()
{
phy_plan_.reset();
equal_expr_[0].reset();
equal_expr_[1].reset();
other_expr_[0].reset();
other_expr_[1].reset();
equal_expr_[0].set_item_count(10);
equal_expr_[1].set_item_count(10);
other_expr_[0].set_item_count(10);
other_expr_[1].set_item_count(10);
hash_join_.reuse();
left_op_.reuse();
right_op_.reuse();
out_data_.reuse();
allocator_.reuse();
}
private:
static void set_id()
{
hash_join_.set_id(0);
left_op_.set_id(1);
right_op_.set_id(2);
out_data_.set_id(3);
}
static void set_column_count(int64_t input_column_count)
{
hash_join_.set_column_count(2 * input_column_count);
left_op_.set_column_count(input_column_count);
right_op_.set_column_count(input_column_count);
out_data_.set_column_count(2 * input_column_count);
}
static int init_equal_conds()
{
int ret = OB_SUCCESS;
// like t1.a = t2.b => (t1.a, t2.b, OP_EQ)
int64_t cond_count = 2;
ObPostExprItem item_col1;
ObPostExprItem item_col2;
ObPostExprItem item_op;
ObExprResType res_type;
res_type.set_calc_type(ObIntType);
for (int64_t i = 0; OB_SUCC(ret) && i < cond_count; ++i) {
item_col1.set_column(i);
item_col2.set_column(i + cond_count);
item_op.set_op(phy_plan_.get_allocator(), "=", 2);
item_op.get_expr_operator()->set_result_type(res_type);
if (OB_FAIL(equal_expr_[i].add_expr_item(item_col1))) {
} else if (OB_FAIL(equal_expr_[i].add_expr_item(item_col2))) {
} else if (OB_FAIL(equal_expr_[i].add_expr_item(item_op))) {
} else if (OB_FAIL(hash_join_.add_equijoin_condition(&equal_expr_[i]))) {
}
}
return ret;
}
static int init_other_conds()
{
int ret = OB_SUCCESS;
// like t1.a + t2.b > 60 => (t1.a, t2.b, OP_ADD, 60, OP_GT)
int64_t cond_count = 1;
ObPostExprItem item_col1;
ObPostExprItem item_col2;
ObPostExprItem item_op_add;
ObPostExprItem item_int;
ObPostExprItem item_op_gt;
ObExprResType res_type_add;
ObExprResType res_type_gt;
res_type_add.set_calc_type(ObIntType);
res_type_gt.set_calc_type(ObIntType);
for (int64_t i = 0; OB_SUCC(ret) && i < cond_count; ++i) {
item_col1.set_column(i);
item_col2.set_column(i + cond_count);
item_op_add.set_op(phy_plan_.get_allocator(), "+", 2);
item_op_add.get_expr_operator()->set_result_type(res_type_add);
item_int.set_int(60);
item_int.set_item_type(T_INT);
item_op_gt.set_op(phy_plan_.get_allocator(), ">", 2);
item_op_gt.get_expr_operator()->set_result_type(res_type_gt);
if (OB_FAIL(other_expr_[i].add_expr_item(item_col1))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_col2))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_add))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_int))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_gt))) {
} else if (OB_FAIL(hash_join_.add_other_join_condition(&other_expr_[i]))) {
}
}
return ret;
}
private:
ObHashJoinPlan();
private:
static ObPhysicalPlan phy_plan_;
static MockSqlExpression equal_expr_[2];
static MockSqlExpression other_expr_[2];
static ObHashJoin hash_join_;
static ObJoinFakeTable left_op_;
static ObJoinFakeTable right_op_;
static ObJoinFakeTable out_data_;
static ObArenaAllocator allocator_;
static int32_t projector_[2];
static int64_t projector_size_;
};
ObPhysicalPlan ObHashJoinPlan::phy_plan_;
MockSqlExpression ObHashJoinPlan::equal_expr_[2];
MockSqlExpression ObHashJoinPlan::other_expr_[2];
ObHashJoin ObHashJoinPlan::hash_join_(ObHashJoinPlan::phy_plan_.get_allocator());
ObJoinFakeTable ObHashJoinPlan::left_op_;
ObJoinFakeTable ObHashJoinPlan::right_op_;
ObJoinFakeTable ObHashJoinPlan::out_data_;
ObArenaAllocator ObHashJoinPlan::allocator_(ObModIds::OB_PAGE_ARENA);
int32_t ObHashJoinPlan::projector_[2];
int64_t ObHashJoinPlan::projector_size_;
ObHashJoinTest::ObHashJoinTest()
{}
ObHashJoinTest::~ObHashJoinTest()
{}
void ObHashJoinTest::join_test(int64_t case_id, ObJoinType join_type)
{
ASSERT_EQ(OB_SUCCESS, ObHashJoinPlan::init(case_id, join_type));
ObExecContext exec_ctx;
ObString tenant_name("test");
uint64_t tenant_id = 1;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ASSERT_EQ(OB_SUCCESS, create_test_session(exec_ctx));
auto my_session = exec_ctx.get_my_session();
ASSERT_TRUE(NULL != my_session);
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session->load_default_sys_variable(false, true));
ASSERT_EQ(OB_SUCCESS, my_session->init_tenant(tenant_name, tenant_id));
ObHashJoin& hash_join = ObHashJoinPlan::get_instance();
ASSERT_EQ(OB_SUCCESS, hash_join.open(exec_ctx));
ObJoinFakeTable& out_data = ObHashJoinPlan::get_out_data();
ASSERT_EQ(OB_SUCCESS, out_data.open(exec_ctx));
int join_ret = OB_SUCCESS;
int out_ret = OB_SUCCESS;
const ObNewRow* join_row = NULL;
const ObNewRow* out_row = NULL;
std::vector<std::vector<int64_t>> join_res;
std::vector<std::vector<int64_t>> out_res;
while (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
join_ret = hash_join.get_next_row(exec_ctx, join_row);
out_ret = out_data.get_next_row(exec_ctx, out_row);
usleep(10 * 1000);
ASSERT_EQ(join_ret, out_ret);
if (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
ObObj* join_cells = join_row->cells_;
std::vector<int64_t> res;
res.resize(4);
for (int i = 0; i < 4; i++) {
res.at(i) = join_cells[i].is_null() ? 0 : join_cells[i].get_int();
}
join_res.push_back(res);
ObObj* out_cells = out_row->cells_;
for (int i = 0; i < 4; i++) {
res.at(i) = out_cells[i].is_null() ? 0 : out_cells[i].get_int();
}
out_res.push_back(res);
}
} // while
auto cmp_func = [](const std::vector<int64_t>& l, std::vector<int64_t> r) {
for (int i = 0; i < l.size(); i++) {
if (l.at(i) != r.at(i)) {
return l.at(i) < r.at(i);
}
}
return false;
};
std::sort(join_res.begin(), join_res.end(), cmp_func);
std::sort(out_res.begin(), out_res.end(), cmp_func);
for (int i = 0; i < join_res.size(); i++) {
ASSERT_FALSE(cmp_func(join_res.at(i), out_res.at(i)));
ASSERT_FALSE(cmp_func(out_res.at(i), join_res.at(i)));
}
ASSERT_EQ(OB_ITER_END, join_ret);
ASSERT_EQ(OB_ITER_END, out_ret);
ASSERT_EQ(OB_ITER_END, hash_join.get_next_row(exec_ctx, join_row));
ASSERT_EQ(OB_ITER_END, out_data.get_next_row(exec_ctx, out_row));
ASSERT_EQ(OB_SUCCESS, hash_join.close(exec_ctx));
ASSERT_EQ(OB_SUCCESS, out_data.close(exec_ctx));
ObHashJoinPlan::reuse();
}
void ObHashJoinTest::serialize_test()
{
ObHashJoin& hash_join_1 = ObHashJoinPlan::get_instance();
ObArenaAllocator alloc;
ObHashJoin hash_join_2(alloc);
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObHashJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
ASSERT_EQ(OB_SUCCESS, hash_join_1.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos));
ASSERT_EQ(pos, hash_join_1.get_serialize_size());
int64_t data_len = pos;
hash_join_2.set_phy_plan(const_cast<ObPhysicalPlan*>(hash_join_1.get_phy_plan()));
pos = 0;
ASSERT_EQ(OB_SUCCESS, hash_join_2.deserialize(buf, data_len, pos));
ASSERT_EQ(pos, data_len);
const char* str_1 = to_cstring(hash_join_1);
const char* str_2 = to_cstring(hash_join_2);
ASSERT_EQ(0, strcmp(str_1, str_2));
ObHashJoinPlan::reuse();
}
void ObHashJoinTest::join_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObExecContext exec_ctx;
const ObNewRow* row = NULL;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ObHashJoin& hash_join = ObHashJoinPlan::get_instance();
if (OB_FAIL(ObHashJoinPlan::init(0, FULL_OUTER_JOIN))) {
} else if (OB_FAIL(hash_join.open(exec_ctx))) {
} else {
while (OB_SUCC(ret)) {
ret = hash_join.get_next_row(exec_ctx, row);
}
if (OB_ITER_END == ret) {
ret = hash_join.close(exec_ctx);
}
}
ObHashJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
void ObHashJoinTest::serialize_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObHashJoin& hash_join = ObHashJoinPlan::get_instance();
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObHashJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
if (OB_FAIL(hash_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {
} else {
int64_t data_len = pos;
pos = 0;
ObHashJoinPlan::reuse();
hash_join.set_phy_plan(ObHashJoinPlan::get_phy_plan());
if (OB_FAIL(hash_join.deserialize(buf, data_len, pos))) {}
}
ObHashJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
void ObHashJoinTest::memlimit_exception_test(int expect_ret, int64_t memsize)
{
int ret = OB_SUCCESS;
ASSERT_EQ(OB_SUCCESS, ObHashJoinPlan::init(0, INNER_JOIN));
// BEGIN_THREAD_CODE(join_test, 8) {
ObExecContext exec_ctx;
ObString tenant_name("test");
uint64_t tenant_id = 1;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ASSERT_EQ(OB_SUCCESS, create_test_session(exec_ctx));
auto my_session = exec_ctx.get_my_session();
ASSERT_TRUE(NULL != my_session);
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session->load_default_sys_variable(false, true));
ASSERT_EQ(OB_SUCCESS, my_session->init_tenant(tenant_name, tenant_id));
ObHashJoin& hash_join = ObHashJoinPlan::get_instance();
oceanbase::lib::set_wa_limit(10, memsize);
ret = hash_join.open(exec_ctx);
ObHashJoinPlan::reuse();
// need remote condition
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
TEST_F(ObHashJoinTest, join_case_0)
{
join_test(0, INNER_JOIN);
join_test(0, LEFT_OUTER_JOIN);
join_test(0, RIGHT_OUTER_JOIN);
join_test(0, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, join_case_1)
{
join_test(1, INNER_JOIN);
join_test(1, LEFT_OUTER_JOIN);
join_test(1, RIGHT_OUTER_JOIN);
join_test(1, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, join_case_2)
{
join_test(2, INNER_JOIN);
join_test(2, LEFT_OUTER_JOIN);
join_test(2, RIGHT_OUTER_JOIN);
join_test(2, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, join_case_3)
{
join_test(3, INNER_JOIN);
join_test(3, LEFT_OUTER_JOIN);
join_test(3, RIGHT_OUTER_JOIN);
join_test(3, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, join_case_4)
{
join_test(4, INNER_JOIN);
join_test(4, LEFT_OUTER_JOIN);
join_test(4, RIGHT_OUTER_JOIN);
join_test(4, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, join_case_5)
{
join_test(5, INNER_JOIN);
join_test(5, LEFT_OUTER_JOIN);
join_test(5, RIGHT_OUTER_JOIN);
join_test(5, FULL_OUTER_JOIN);
}
TEST_F(ObHashJoinTest, memlimit_test)
{
memlimit_exception_test(OB_ALLOCATE_MEMORY_FAILED, 100 * 1024 * 1024);
memlimit_exception_test(OB_SUCCESS, 100 * 1024 * 1024);
}
#define JOIN_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
join_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
#define SERIALIZE_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
serialize_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
int main(int argc, char** argv)
{
init_sql_factories();
OB_LOGGER.set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
OB_LOGGER.disable();
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
/**
* 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.
*/
#ifndef OB_JOIN_FAKE_TABLE_H_
#define OB_JOIN_FAKE_TABLE_H_
#include "sql/engine/join/ob_join.h"
#include "sql/engine/ob_physical_plan_ctx.h"
#include "sql/engine/ob_phy_operator.h"
#include "sql/engine/ob_exec_context.h"
#include "sql/ob_sql_define.h"
namespace oceanbase {
using namespace common;
namespace sql {
namespace test {
enum TableType { TT_UNKNOWN, TT_LEFT_TABLE, TT_RIGHT_TABLE, TT_OUT_TABLE };
enum JoinOpTestType {
MERGE_JOIN_TEST,
NL_JOIN_TEST,
BNL_JOIN_TEST,
HASH_JOIN_TEST,
JOIN_TEST_TYPE_NUM,
};
static const int DATA_COUNT = 16;
typedef struct {
int64_t left_[DATA_COUNT][2];
int64_t right_[DATA_COUNT][2];
int64_t out_inner_[DATA_COUNT * DATA_COUNT][4];
int64_t out_left_[DATA_COUNT * DATA_COUNT][4];
int64_t out_right_[DATA_COUNT * DATA_COUNT][4];
int64_t out_full_[DATA_COUNT * DATA_COUNT][4];
} JoinData;
class ObQueryRangeDummy {
public:
ObQueryRangeDummy() : scan_key_value_(0)
{}
~ObQueryRangeDummy()
{}
void set_scan_key_value(int64_t join_key_value)
{
scan_key_value_ = join_key_value;
}
int64_t get_scan_key_value()
{
return scan_key_value_;
}
private:
int64_t scan_key_value_;
};
class ObJoinFakeTableScanInput : public ObIPhyOperatorInput {
public:
virtual int init(ObExecContext& ctx, ObTaskInfo& task_info, ObPhyOperator& op)
{
UNUSED(ctx);
UNUSED(task_info);
UNUSED(op);
return OB_SUCCESS;
}
virtual ObPhyOperatorType get_phy_op_type() const
{
return PHY_TABLE_SCAN;
}
ObQueryRangeDummy& get_query_range()
{
return query_range_;
}
private:
ObQueryRangeDummy query_range_;
};
static ObArenaAllocator alloc_;
class ObJoinFakeTable : public ObPhyOperator {
protected:
class ObJoinFakeTableCtx : public ObPhyOperatorCtx {
friend class ObJoinFakeTable;
public:
ObJoinFakeTableCtx(ObExecContext& exex_ctx) : ObPhyOperatorCtx(exex_ctx), iter_(0)
{}
virtual void destroy()
{
return ObPhyOperatorCtx::destroy_base();
}
private:
int64_t iter_;
common::ObAddr server_;
};
public:
ObJoinFakeTable();
virtual ~ObJoinFakeTable();
int init(JoinOpTestType join_op_type);
virtual ObPhyOperatorType get_type() const
{
return op_type_;
}
virtual int set_child(int32_t child_idx, ObPhyOperator& child_operator);
virtual ObPhyOperator* get_child(int32_t child_idx) const;
virtual int32_t get_child_num() const
{
return 0;
}
virtual int inner_open(ObExecContext& exec_ctx) const;
virtual int rescan(ObExecContext& exec_ctx) const;
virtual int init_op_ctx(ObExecContext& exec_ctx) const;
virtual int create_operator_input(ObExecContext& exec_ctx) const;
virtual int inner_get_next_row(ObExecContext& exec_ctx, const common::ObNewRow*& row) const;
public:
int prepare_data(int64_t case_id, TableType table_type, ObJoinType join_type);
void set_type(ObPhyOperatorType op_type)
{
op_type_ = op_type;
}
private:
int cons_row(int64_t col1, int64_t col2, common::ObNewRow& row) const;
int cons_row(int64_t col1, int64_t col2, int64_t col3, int64_t col4, common::ObNewRow& row) const;
private:
int64_t (*left_data_)[2];
int64_t (*right_data_)[2];
int64_t (*out_data_)[4];
JoinOpTestType join_op_type_;
ObPhyOperatorType op_type_;
bool is_inited_;
};
} // namespace test
} // namespace sql
} // namespace oceanbase
#endif /* OB_JOIN_FAKE_TABLE_H_ */

View File

@ -0,0 +1,521 @@
/**
* 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 "lib/utility/ob_test_util.h"
#include <gtest/gtest.h>
#define private public
#define protected public
#include "ob_join_fake_table.h"
#include "sql/engine/join/ob_merge_join.h"
#include "sql/engine/expr/ob_expr_equal.h"
#include "sql/engine/expr/ob_expr_mod.h"
#include "sql/ob_sql_init.h"
#include "sql/session/ob_sql_session_info.h"
#include "lib/utility/ob_tracepoint.h"
#include "observer/ob_server.h"
#include "observer/ob_server_struct.h"
#include "share/ob_tenant_mgr.h"
#include "sql/engine/test_engine_util.h"
using namespace oceanbase::sql;
using namespace oceanbase::sql::test;
using namespace oceanbase::common;
using namespace oceanbase::observer;
using namespace oceanbase::share;
class MockSqlExpression : public ObSqlExpression {
public:
MockSqlExpression() : ObSqlExpression(alloc_)
{
set_item_count(10);
}
~MockSqlExpression()
{}
};
class ObMergeJoinTest : public ::testing::Test {
public:
ObMergeJoinTest();
virtual ~ObMergeJoinTest();
protected:
void join_test(int64_t case_id, ObJoinType join_type);
void serialize_test();
void join_exception_test(int expect_ret);
void serialize_exception_test(int expect_ret);
// disallow copy
ObMergeJoinTest(const ObMergeJoinTest& other);
ObMergeJoinTest& operator=(const ObMergeJoinTest& other);
private:
// data members
};
class ObMergeJoinPlan {
public:
static ObMergeJoin& get_instance()
{
return merge_join_;
}
static ObJoinFakeTable& get_out_data()
{
return out_data_;
}
static ObPhysicalPlan* get_phy_plan()
{
return &phy_plan_;
}
static int init(int64_t case_id, ObJoinType join_type)
{
int ret = OB_SUCCESS;
if (OB_FAIL(left_op_.init(MERGE_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "left op init failed", K(ret));
} else if (OB_FAIL(right_op_.init(MERGE_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "right op init failed", K(ret));
} else if (OB_FAIL(out_data_.init(MERGE_JOIN_TEST))) {
SQL_ENG_LOG(WARN, "out data init failed", K(ret));
} else {
merge_join_.set_phy_plan(&phy_plan_);
left_op_.set_phy_plan(&phy_plan_);
right_op_.set_phy_plan(&phy_plan_);
out_data_.set_phy_plan(&phy_plan_);
set_id();
set_column_count(2);
projector_[0] = 0;
projector_[1] = 1;
projector_size_ = 2;
left_op_.set_projector(projector_, projector_size_);
right_op_.set_projector(projector_, projector_size_);
ObArray<ObOrderDirection> array;
ObOrderDirection d1 = oceanbase::sql::NULLS_FIRST_ASC;
ObOrderDirection d2 = oceanbase::sql::NULLS_FIRST_ASC;
array.push_back(d1);
array.push_back(d2);
if (OB_FAIL(merge_join_.set_child(0, left_op_))) {
} else if (OB_FAIL(merge_join_.set_child(1, right_op_))) {
} else if (OB_FAIL(merge_join_.set_join_type(join_type))) {
} else if (OB_FAIL(merge_join_.set_merge_directions(array))) {
} else if (OB_FAIL(merge_join_.set_join_type(join_type))) {
} else if (OB_FAIL(init_equal_conds())) {
} else if (OB_FAIL(init_other_conds())) {
} else if (OB_FAIL(left_op_.prepare_data(case_id, TT_LEFT_TABLE, join_type))) {
} else if (OB_FAIL(right_op_.prepare_data(case_id, TT_RIGHT_TABLE, join_type))) {
} else if (OB_FAIL(out_data_.prepare_data(case_id, TT_OUT_TABLE, join_type))) {
}
}
return ret;
}
static void reuse()
{
phy_plan_.reset();
equal_expr_[0].reset();
equal_expr_[1].reset();
other_expr_[0].reset();
other_expr_[1].reset();
equal_expr_[0].set_item_count(10);
equal_expr_[1].set_item_count(10);
other_expr_[0].set_item_count(10);
other_expr_[1].set_item_count(10);
merge_join_.reuse();
left_op_.reuse();
right_op_.reuse();
out_data_.reuse();
allocator_.reuse();
}
private:
static void set_id()
{
merge_join_.set_id(0);
left_op_.set_id(1);
right_op_.set_id(2);
out_data_.set_id(3);
}
static void set_column_count(int64_t input_column_count)
{
merge_join_.set_column_count(2 * input_column_count);
left_op_.set_column_count(input_column_count);
right_op_.set_column_count(input_column_count);
out_data_.set_column_count(2 * input_column_count);
}
static int init_equal_conds()
{
int ret = OB_SUCCESS;
// like t1.a = t2.b => (t1.a, t2.b, OP_EQ)
int64_t cond_count = 2;
ObPostExprItem item_col1;
ObPostExprItem item_col2;
ObPostExprItem item_op;
ObExprResType res_type;
res_type.set_calc_type(ObIntType);
for (int64_t i = 0; OB_SUCC(ret) && i < cond_count; ++i) {
item_col1.set_column(i);
item_col2.set_column(i + cond_count);
item_op.set_op(phy_plan_.get_allocator(), "=", 2);
item_op.get_expr_operator()->set_result_type(res_type);
if (OB_FAIL(equal_expr_[i].add_expr_item(item_col1))) {
} else if (OB_FAIL(equal_expr_[i].add_expr_item(item_col2))) {
} else if (OB_FAIL(equal_expr_[i].add_expr_item(item_op))) {
} else if (OB_FAIL(merge_join_.add_equijoin_condition(&equal_expr_[i]))) {
}
}
return ret;
}
static int init_other_conds()
{
int ret = OB_SUCCESS;
// like t1.a + t2.b > 60 => (t1.a, t2.b, OP_ADD, 60, OP_GT)
int64_t cond_count = 1;
ObPostExprItem item_col1;
ObPostExprItem item_col2;
ObPostExprItem item_op_add;
ObPostExprItem item_int;
ObPostExprItem item_op_gt;
ObExprResType res_type_add;
ObExprResType res_type_gt;
res_type_add.set_calc_type(ObIntType);
res_type_gt.set_calc_type(ObIntType);
for (int64_t i = 0; OB_SUCC(ret) && i < cond_count; ++i) {
item_col1.set_column(i);
item_col2.set_column(i + cond_count);
item_op_add.set_op(phy_plan_.get_allocator(), "+", 2);
item_op_add.get_expr_operator()->set_result_type(res_type_add);
item_int.set_int(60);
item_int.set_item_type(T_INT);
item_op_gt.set_op(phy_plan_.get_allocator(), ">", 2);
item_op_gt.get_expr_operator()->set_result_type(res_type_gt);
if (OB_FAIL(other_expr_[i].add_expr_item(item_col1))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_col2))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_add))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_int))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_gt))) {
} else if (OB_FAIL(merge_join_.add_other_join_condition(&other_expr_[i]))) {
}
}
return ret;
}
private:
ObMergeJoinPlan();
private:
static ObPhysicalPlan phy_plan_;
static MockSqlExpression equal_expr_[2];
static MockSqlExpression other_expr_[2];
static ObMergeJoin merge_join_;
static ObJoinFakeTable left_op_;
static ObJoinFakeTable right_op_;
static ObJoinFakeTable out_data_;
static ObArenaAllocator allocator_;
static int32_t projector_[2];
static int64_t projector_size_;
};
ObPhysicalPlan ObMergeJoinPlan::phy_plan_;
MockSqlExpression ObMergeJoinPlan::equal_expr_[2];
MockSqlExpression ObMergeJoinPlan::other_expr_[2];
ObMergeJoin ObMergeJoinPlan::merge_join_(ObMergeJoinPlan::phy_plan_.get_allocator());
ObJoinFakeTable ObMergeJoinPlan::left_op_;
ObJoinFakeTable ObMergeJoinPlan::right_op_;
ObJoinFakeTable ObMergeJoinPlan::out_data_;
ObArenaAllocator ObMergeJoinPlan::allocator_(ObModIds::OB_PAGE_ARENA);
int32_t ObMergeJoinPlan::projector_[2];
int64_t ObMergeJoinPlan::projector_size_;
ObMergeJoinTest::ObMergeJoinTest()
{}
ObMergeJoinTest::~ObMergeJoinTest()
{}
void ObMergeJoinTest::join_test(int64_t case_id, ObJoinType join_type)
{
ASSERT_EQ(OB_SUCCESS, ObMergeJoinPlan::init(case_id, join_type));
// BEGIN_THREAD_CODE(join_test, 8) {
ObExecContext exec_ctx;
ObString tenant_name("test");
uint64_t tenant_id = 1;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ASSERT_EQ(OB_SUCCESS, create_test_session(exec_ctx));
auto my_session = exec_ctx.get_my_session();
ASSERT_TRUE(NULL != my_session);
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session->load_default_sys_variable(false, true));
ASSERT_EQ(OB_SUCCESS, my_session->init_tenant(tenant_name, tenant_id));
ObMergeJoin& merge_join = ObMergeJoinPlan::get_instance();
ASSERT_EQ(OB_SUCCESS, merge_join.open(exec_ctx));
ObJoinFakeTable& out_data = ObMergeJoinPlan::get_out_data();
ASSERT_EQ(OB_SUCCESS, out_data.open(exec_ctx));
int join_ret = OB_SUCCESS;
int out_ret = OB_SUCCESS;
const ObNewRow* join_row = NULL;
const ObNewRow* out_row = NULL;
while (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
join_ret = merge_join.get_next_row(exec_ctx, join_row);
out_ret = out_data.get_next_row(exec_ctx, out_row);
usleep(10 * 1000);
ASSERT_EQ(join_ret, out_ret);
if (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
ObObj* join_cells = join_row->cells_;
int64_t join_cell0 = join_cells[0].is_null() ? 0 : join_cells[0].get_int();
int64_t join_cell1 = join_cells[1].is_null() ? 0 : join_cells[1].get_int();
int64_t join_cell2 = join_cells[2].is_null() ? 0 : join_cells[2].get_int();
int64_t join_cell3 = join_cells[3].is_null() ? 0 : join_cells[3].get_int();
ObObj* out_cells = out_row->cells_;
int64_t out_cell0 = out_cells[0].is_null() ? 0 : out_cells[0].get_int();
int64_t out_cell1 = out_cells[1].is_null() ? 0 : out_cells[1].get_int();
int64_t out_cell2 = out_cells[2].is_null() ? 0 : out_cells[2].get_int();
int64_t out_cell3 = out_cells[3].is_null() ? 0 : out_cells[3].get_int();
ASSERT_EQ(join_cell0, out_cell0);
ASSERT_EQ(join_cell1, out_cell1);
ASSERT_EQ(join_cell2, out_cell2);
ASSERT_EQ(join_cell3, out_cell3);
}
} // while
ASSERT_EQ(OB_ITER_END, join_ret);
ASSERT_EQ(OB_ITER_END, out_ret);
ASSERT_EQ(OB_ITER_END, merge_join.get_next_row(exec_ctx, join_row));
ASSERT_EQ(OB_ITER_END, out_data.get_next_row(exec_ctx, out_row));
ASSERT_EQ(OB_SUCCESS, merge_join.close(exec_ctx));
ASSERT_EQ(OB_SUCCESS, out_data.close(exec_ctx));
// } END_THREAD_CODE(join_test);
ObMergeJoinPlan::reuse();
}
void ObMergeJoinTest::serialize_test()
{
ObMergeJoin& merge_join_1 = ObMergeJoinPlan::get_instance();
ObArenaAllocator alloc;
ObMergeJoin merge_join_2(alloc);
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObMergeJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
ASSERT_EQ(OB_SUCCESS, merge_join_1.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos));
ASSERT_EQ(pos, merge_join_1.get_serialize_size());
int64_t data_len = pos;
merge_join_2.set_phy_plan(const_cast<ObPhysicalPlan*>(merge_join_1.get_phy_plan()));
pos = 0;
ASSERT_EQ(OB_SUCCESS, merge_join_2.deserialize(buf, data_len, pos));
ASSERT_EQ(pos, data_len);
const char* str_1 = to_cstring(merge_join_1);
const char* str_2 = to_cstring(merge_join_2);
ASSERT_EQ(0, strcmp(str_1, str_2));
ObMergeJoinPlan::reuse();
}
void ObMergeJoinTest::join_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObExecContext exec_ctx;
const ObNewRow* row = NULL;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ObMergeJoin& merge_join = ObMergeJoinPlan::get_instance();
if (OB_FAIL(ObMergeJoinPlan::init(0, FULL_OUTER_JOIN))) {
} else if (OB_FAIL(merge_join.open(exec_ctx))) {
} else {
while (OB_SUCC(ret)) {
ret = merge_join.get_next_row(exec_ctx, row);
}
if (OB_ITER_END == ret) {
ret = merge_join.close(exec_ctx);
}
}
ObMergeJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
void ObMergeJoinTest::serialize_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObMergeJoin& merge_join = ObMergeJoinPlan::get_instance();
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObMergeJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
if (OB_FAIL(merge_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {
} else {
int64_t data_len = pos;
pos = 0;
ObMergeJoinPlan::reuse();
merge_join.set_phy_plan(ObMergeJoinPlan::get_phy_plan());
if (OB_FAIL(merge_join.deserialize(buf, data_len, pos))) {}
}
ObMergeJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
TEST_F(ObMergeJoinTest, join_case_0)
{
join_test(0, INNER_JOIN);
join_test(0, LEFT_OUTER_JOIN);
join_test(0, RIGHT_OUTER_JOIN);
join_test(0, FULL_OUTER_JOIN);
}
TEST_F(ObMergeJoinTest, join_case_1)
{
join_test(1, INNER_JOIN);
join_test(1, LEFT_OUTER_JOIN);
join_test(1, RIGHT_OUTER_JOIN);
join_test(1, FULL_OUTER_JOIN);
}
TEST_F(ObMergeJoinTest, join_case_2)
{
join_test(2, INNER_JOIN);
join_test(2, LEFT_OUTER_JOIN);
join_test(2, RIGHT_OUTER_JOIN);
join_test(2, FULL_OUTER_JOIN);
}
TEST_F(ObMergeJoinTest, join_case_3)
{
join_test(3, INNER_JOIN);
join_test(3, LEFT_OUTER_JOIN);
join_test(3, RIGHT_OUTER_JOIN);
join_test(3, FULL_OUTER_JOIN);
}
TEST_F(ObMergeJoinTest, join_case_4)
{
join_test(4, INNER_JOIN);
join_test(4, LEFT_OUTER_JOIN);
join_test(4, RIGHT_OUTER_JOIN);
join_test(4, FULL_OUTER_JOIN);
}
TEST_F(ObMergeJoinTest, join_case_5)
{
join_test(5, INNER_JOIN);
join_test(5, LEFT_OUTER_JOIN);
join_test(5, RIGHT_OUTER_JOIN);
join_test(5, FULL_OUTER_JOIN);
}
// TEST_F(ObMergeJoinTest, serialize_case_0)
//{
// serialize_test();
//}
#define JOIN_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
join_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
// TEST_F(ObMergeJoinTest, join_exception_0)
//{
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "open", "t1", -1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "open", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "open", "t5", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "open", "t7", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "open", "t9", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "close", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "inner_get_next_row", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "inner_get_next_row", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "inner_get_next_row", "t5", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "inner_get_next_row", "t7", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "join_begin_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "left_join_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "left_join_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "right_join_cache_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "right_join_cache_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "right_join_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "right_join_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "read_cache_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "read_cache_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "read_cache_func_end", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "full_cache_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "full_cache_operate", "t3", OB_ITER_END, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "full_cache_func_equal", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "empty_cache_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "empty_cache_operate", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "empty_cache_func_equal", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "empty_cache_func_diff", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "empty_cache_func_diff", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "fill_cache_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "fill_cache_func_equal", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "fill_cache_func_diff_end", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_read_cache", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_read_cache", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_fill_cache", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_fill_cache", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_fill_cache", "t5", OB_ERROR, OB_ERROR);
//}
//
// TEST_F(ObMergeJoinTest, join_exception_1)
//{
// JOIN_EXCEPTION_TEST("ob_join.cpp", "open", "t1", UNKNOWN_JOIN, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "open", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t1", 1, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t3", 1, OB_ALLOCATE_MEMORY_FAILED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t5", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t1", 1, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t3", 1, OB_ALLOCATE_MEMORY_FAILED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t5", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "join_rows", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "left_join_rows", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "right_join_rows", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "calc_equal_conds", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "calc_other_conds", "t1", OB_ERROR, OB_ERROR);
//}
#define SERIALIZE_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
serialize_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
// TEST_F(ObMergeJoinTest, serialize_exception)
//{
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t3", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t5", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t7", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t9", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t3", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t5", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t7", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t9", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t11", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t13", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t15", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t17", OB_ERROR, OB_ERROR);
//}
int main(int argc, char** argv)
{
OB_LOGGER.set_log_level("WARN");
oceanbase::lib::set_memory_limit(20L << 30);
init_sql_factories();
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
OB_LOGGER.disable();
return ret;
}

View File

@ -0,0 +1,431 @@
/**
* 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 "sql/engine/join/ob_nested_loop_join.h"
#include "lib/utility/ob_test_util.h"
#include "ob_join_fake_table.h"
#include <gtest/gtest.h>
#include "sql/engine/expr/ob_expr_equal.h"
#include "sql/engine/expr/ob_expr_mod.h"
#include "sql/ob_sql_init.h"
#include "lib/utility/ob_tracepoint.h"
using namespace oceanbase::sql;
using namespace oceanbase::sql::test;
using namespace oceanbase::common;
class ObNestedLoopJoinTest : public ::testing::Test {
public:
ObNestedLoopJoinTest();
virtual ~ObNestedLoopJoinTest();
protected:
void join_test(int64_t case_id, ObJoinType join_type);
void serialize_test();
void join_exception_test(int expect_ret);
void serialize_exception_test(int expect_ret);
// disallow copy
ObNestedLoopJoinTest(const ObNestedLoopJoinTest& other);
ObNestedLoopJoinTest& operator=(const ObNestedLoopJoinTest& other);
private:
// data members
};
class ObNestedLoopJoinPlan {
public:
static ObNestedLoopJoin& get_instance()
{
return nested_loop_join_;
}
static ObJoinFakeTable& get_out_data()
{
return out_data_;
}
static ObPhysicalPlan* get_phy_plan()
{
return &phy_plan_;
}
static int init(int64_t case_id, ObJoinType join_type)
{
int ret = OB_SUCCESS;
nested_loop_join_.set_phy_plan(&phy_plan_);
set_id();
set_column_count(2);
right_op_.set_type(PHY_TABLE_SCAN);
if (OB_FAIL(nested_loop_join_.set_child(0, left_op_))) {
} else if (OB_FAIL(nested_loop_join_.set_child(1, right_op_))) {
} else if (OB_FAIL(nested_loop_join_.set_join_type(join_type))) {
} else if (OB_FAIL(init_scan_index())) {
} else if (OB_FAIL(init_equal_conds())) {
} else if (OB_FAIL(init_other_conds())) {
} else if (OB_FAIL(left_op_.prepare_data(case_id, TT_LEFT_TABLE, join_type))) {
} else if (OB_FAIL(right_op_.prepare_data(case_id, TT_RIGHT_TABLE, join_type))) {
} else if (OB_FAIL(out_data_.prepare_data(case_id, TT_OUT_TABLE, join_type))) {
}
return ret;
}
static void reuse()
{
phy_plan_.reset();
equal_expr_[0].reset();
equal_expr_[1].reset();
other_expr_[0].reset();
other_expr_[1].reset();
nested_loop_join_.reuse();
left_op_.reuse();
right_op_.reuse();
out_data_.reuse();
allocator_.reuse();
}
private:
static void set_id()
{
nested_loop_join_.set_id(0);
left_op_.set_id(1);
right_op_.set_id(2);
out_data_.set_id(3);
}
static void set_column_count(int64_t input_column_count)
{
nested_loop_join_.set_column_count(2 * input_column_count);
left_op_.set_column_count(input_column_count);
right_op_.set_column_count(input_column_count);
out_data_.set_column_count(2 * input_column_count);
}
static int init_scan_index()
{
int ret = OB_SUCCESS;
int64_t idx = 0;
if (OB_FAIL(nested_loop_join_.add_left_scan_index(idx))) {}
return ret;
}
static int init_equal_conds()
{
int ret = OB_SUCCESS;
// like t1.a = t2.b => (t1.a, t2.b, OP_EQ)
ObPostExprItem item_col;
ObPostExprItem item_op;
int64_t idx = 1;
item_col.set_column(idx);
item_op.set_op("=", 2);
if (OB_FAIL(equal_expr_[idx].add_expr_item(item_col))) {
} else if (OB_FAIL(equal_expr_[idx].add_expr_item(item_col))) {
} else if (OB_FAIL(equal_expr_[idx].add_expr_item(item_op))) {
} else if (OB_FAIL(nested_loop_join_.add_equijoin_condition(&equal_expr_[idx]))) {
}
return ret;
}
static int init_other_conds()
{
int ret = OB_SUCCESS;
// like t1.a + t2.b > 60 => (t1.a, t2.b, OP_ADD, 60, OP_GT)
int64_t cond_count = 1;
ObPostExprItem item_col;
ObPostExprItem item_op_add;
ObPostExprItem item_int;
ObPostExprItem item_op_gt;
for (int64_t i = 0; OB_SUCC(ret) && i < cond_count; ++i) {
item_col.set_column(i);
item_op_add.set_op("+", 2);
item_int.set_int(60);
item_int.set_item_type(T_INT);
item_op_gt.set_op(">", 2);
if (OB_FAIL(other_expr_[i].add_expr_item(item_col))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_col))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_add))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_int))) {
} else if (OB_FAIL(other_expr_[i].add_expr_item(item_op_gt))) {
} else if (OB_FAIL(nested_loop_join_.add_other_join_condition(&other_expr_[i]))) {
}
}
return ret;
}
private:
ObNestedLoopJoinPlan();
private:
static ObPhysicalPlan phy_plan_;
static ObSqlExpression equal_expr_[2];
static ObSqlExpression other_expr_[2];
static ObSqlExpression param_expr_[2];
static ObNestedLoopJoin nested_loop_join_;
static ObJoinFakeTable left_op_;
static ObJoinFakeTable right_op_;
static ObJoinFakeTable out_data_;
static ObArenaAllocator allocator_;
};
ObPhysicalPlan ObNestedLoopJoinPlan::phy_plan_;
ObSqlExpression ObNestedLoopJoinPlan::equal_expr_[2];
ObSqlExpression ObNestedLoopJoinPlan::other_expr_[2];
ObSqlExpression ObNestedLoopJoinPlan::param_expr_[2];
ObNestedLoopJoin ObNestedLoopJoinPlan::nested_loop_join_(ObNestedLoopJoinPlan::phy_plan_.get_allocator());
ObJoinFakeTable ObNestedLoopJoinPlan::left_op_;
ObJoinFakeTable ObNestedLoopJoinPlan::right_op_;
ObJoinFakeTable ObNestedLoopJoinPlan::out_data_;
ObArenaAllocator ObNestedLoopJoinPlan::allocator_(ObModIds::OB_PAGE_ARENA);
ObNestedLoopJoinTest::ObNestedLoopJoinTest()
{}
ObNestedLoopJoinTest::~ObNestedLoopJoinTest()
{}
void ObNestedLoopJoinTest::join_test(int64_t case_id, ObJoinType join_type)
{
ASSERT_EQ(OB_SUCCESS, ObNestedLoopJoinPlan::init(case_id, join_type));
BEGIN_THREAD_CODE(join_test, 8)
{
ObExecContext exec_ctx;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ObNestedLoopJoin& nested_loop_join = ObNestedLoopJoinPlan::get_instance();
ASSERT_EQ(OB_SUCCESS, nested_loop_join.open(exec_ctx));
ObJoinFakeTable& out_data = ObNestedLoopJoinPlan::get_out_data();
ASSERT_EQ(OB_SUCCESS, out_data.open(exec_ctx));
int join_ret = OB_SUCCESS;
int out_ret = OB_SUCCESS;
const ObNewRow* join_row = NULL;
const ObNewRow* out_row = NULL;
while (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
join_ret = nested_loop_join.get_next_row(exec_ctx, join_row);
out_ret = out_data.get_next_row(exec_ctx, out_row);
usleep(10 * 1000);
ASSERT_EQ(join_ret, out_ret);
if (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
ObObj* join_cells = join_row->cells_;
int64_t join_cell0 = join_cells[0].is_null() ? 0 : join_cells[0].get_int();
int64_t join_cell1 = join_cells[1].is_null() ? 0 : join_cells[1].get_int();
int64_t join_cell2 = join_cells[2].is_null() ? 0 : join_cells[2].get_int();
int64_t join_cell3 = join_cells[3].is_null() ? 0 : join_cells[3].get_int();
ObObj* out_cells = out_row->cells_;
int64_t out_cell0 = out_cells[0].is_null() ? 0 : out_cells[0].get_int();
int64_t out_cell1 = out_cells[1].is_null() ? 0 : out_cells[1].get_int();
int64_t out_cell2 = out_cells[2].is_null() ? 0 : out_cells[2].get_int();
int64_t out_cell3 = out_cells[3].is_null() ? 0 : out_cells[3].get_int();
ASSERT_EQ(join_cell0, out_cell0);
ASSERT_EQ(join_cell1, out_cell1);
ASSERT_EQ(join_cell2, out_cell2);
ASSERT_EQ(join_cell3, out_cell3);
}
} // while
ASSERT_EQ(OB_ITER_END, join_ret);
ASSERT_EQ(OB_ITER_END, out_ret);
ASSERT_EQ(OB_ITER_END, nested_loop_join.get_next_row(exec_ctx, join_row));
ASSERT_EQ(OB_ITER_END, out_data.get_next_row(exec_ctx, out_row));
ASSERT_EQ(OB_SUCCESS, nested_loop_join.close(exec_ctx));
ASSERT_EQ(OB_SUCCESS, out_data.close(exec_ctx));
}
END_THREAD_CODE(join_test);
ObNestedLoopJoinPlan::reuse();
}
void ObNestedLoopJoinTest::serialize_test()
{
ObNestedLoopJoin& nested_loop_join_1 = ObNestedLoopJoinPlan::get_instance();
ObNestedLoopJoin nested_loop_join_2;
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObNestedLoopJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
ASSERT_EQ(OB_SUCCESS, nested_loop_join_1.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos));
ASSERT_EQ(pos, nested_loop_join_1.get_serialize_size());
int64_t data_len = pos;
nested_loop_join_2.set_phy_plan(const_cast<ObPhysicalPlan*>(nested_loop_join_1.get_phy_plan()));
pos = 0;
ASSERT_EQ(OB_SUCCESS, nested_loop_join_2.deserialize(buf, data_len, pos));
ASSERT_EQ(pos, data_len);
const char* str_1 = to_cstring(nested_loop_join_1);
const char* str_2 = to_cstring(nested_loop_join_2);
ASSERT_EQ(0, strcmp(str_1, str_2));
ObNestedLoopJoinPlan::reuse();
}
void ObNestedLoopJoinTest::join_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObExecContext exec_ctx;
const ObNewRow* row = NULL;
ASSERT_EQ(OB_SUCCESS, exec_ctx.init_phy_op(4));
ASSERT_EQ(OB_SUCCESS, exec_ctx.create_physical_plan_ctx());
ObNestedLoopJoin& nested_loop_join = ObNestedLoopJoinPlan::get_instance();
if (OB_FAIL(ObNestedLoopJoinPlan::init(0, LEFT_OUTER_JOIN))) {
} else if (OB_FAIL(nested_loop_join.open(exec_ctx))) {
} else {
while (OB_SUCC(ret)) {
ret = nested_loop_join.get_next_row(exec_ctx, row);
}
if (OB_ITER_END == ret) {
ret = nested_loop_join.close(exec_ctx);
}
}
ObNestedLoopJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
void ObNestedLoopJoinTest::serialize_exception_test(int expect_ret)
{
int ret = OB_SUCCESS;
ObNestedLoopJoin& nested_loop_join = ObNestedLoopJoinPlan::get_instance();
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
ASSERT_EQ(OB_SUCCESS, ObNestedLoopJoinPlan::init(0, INNER_JOIN));
int64_t pos = 0;
if (OB_FAIL(nested_loop_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {
} else {
int64_t data_len = pos;
pos = 0;
ObNestedLoopJoinPlan::reuse();
nested_loop_join.set_phy_plan(ObNestedLoopJoinPlan::get_phy_plan());
if (OB_FAIL(nested_loop_join.deserialize(buf, data_len, pos))) {}
}
ObNestedLoopJoinPlan::reuse();
if (OB_FAIL(ret)) {
ASSERT_EQ(expect_ret, ret);
}
}
TEST_F(ObNestedLoopJoinTest, join_case_0)
{
join_test(0, INNER_JOIN);
join_test(0, LEFT_OUTER_JOIN);
}
TEST_F(ObNestedLoopJoinTest, join_case_1)
{
join_test(1, INNER_JOIN);
join_test(1, LEFT_OUTER_JOIN);
}
TEST_F(ObNestedLoopJoinTest, join_case_2)
{
join_test(2, INNER_JOIN);
join_test(2, LEFT_OUTER_JOIN);
}
TEST_F(ObNestedLoopJoinTest, join_case_3)
{
join_test(3, INNER_JOIN);
join_test(3, LEFT_OUTER_JOIN);
}
TEST_F(ObNestedLoopJoinTest, join_case_4)
{
join_test(4, INNER_JOIN);
join_test(4, LEFT_OUTER_JOIN);
}
TEST_F(ObNestedLoopJoinTest, join_case_5)
{
join_test(5, INNER_JOIN);
join_test(5, LEFT_OUTER_JOIN);
}
// TEST_F(ObNestedLoopJoinTest, serialize_case_0)
//{
// serialize_test();
//}
#define JOIN_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
join_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
// TEST_F(ObNestedLoopJoinTest, join_exception_0)
//{
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "open", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "open", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "open", "t5", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "close", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "inner_get_next_row", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "inner_get_next_row", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "inner_get_next_row", "t5", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "inner_create_operator_ctx", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_left_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_left_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_left_func_going", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_right_operate", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_right_func_going", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_right_func_going", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_right_func_going", "t5", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "read_right_func_end", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "calc_right_query_range", "t1", -1, OB_NOT_IMPLEMENT);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "calc_right_query_range", "t3", 1, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "calc_right_query_range", "t5", 1, OB_NOT_INIT);
//}
//
// TEST_F(ObNestedLoopJoinTest, join_exception_1)
//{
// JOIN_EXCEPTION_TEST("ob_join.cpp", "open", "t1", UNKNOWN_JOIN, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "open", "t3", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t1", 1, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t3", 1, OB_ALLOCATE_MEMORY_FAILED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_equijoin_condition", "t5", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t1", 1, OB_NOT_INIT);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t3", 1, OB_ALLOCATE_MEMORY_FAILED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "add_other_join_condition", "t5", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "join_rows", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "left_join_rows", "t1", 1, OB_ERR_UNEXPECTED);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "calc_equal_conds", "t1", OB_ERROR, OB_ERROR);
// JOIN_EXCEPTION_TEST("ob_join.cpp", "calc_other_conds", "t1", OB_ERROR, OB_ERROR);
//}
#define SERIALIZE_EXCEPTION_TEST(file, func, key, err, expect_ret) \
do { \
TP_SET_ERROR("engine/join/" file, func, key, err); \
serialize_exception_test(expect_ret); \
TP_SET_ERROR("engine/join/" file, func, key, NULL); \
} while (0)
// TEST_F(ObNestedLoopJoinTest, serialize_exception)
//{
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t3", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t5", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t7", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "serialize", "t9", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t3", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t5", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t7", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t9", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t11", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t13", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t15", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t17", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_nested_loop_join.cpp", "serialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_nested_loop_join.cpp", "serialize", "t3", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_nested_loop_join.cpp", "deserialize", "t1", OB_ERROR, OB_ERROR);
// SERIALIZE_EXCEPTION_TEST("ob_nested_loop_join.cpp", "deserialize", "t3", OB_ERROR, OB_ERROR);
//}
int main(int argc, char** argv)
{
init_sql_factories();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,848 @@
/**
* 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.
*/
#define USING_LOG_PREFIX SQL
#include <gtest/gtest.h>
#define private public
#define protected public
#include "sql/engine/join/ob_hash_join.h"
#include "sql/engine/join/ob_merge_join.h"
#include "share/system_variable/ob_system_variable.h"
#include "storage/blocksstable/ob_data_file_prepare.h"
#include "join_data_generator.h"
#include "sql/ob_sql_init.h"
#include "sql/engine/ob_sql_mem_mgr_processor.h"
#include "observer/omt/ob_tenant_config_mgr.h"
namespace oceanbase {
namespace sql {
using namespace common;
using namespace share;
using namespace omt;
class MockSqlExpression : public ObSqlExpression {
public:
MockSqlExpression(ObIAllocator& alloc) : ObSqlExpression(alloc)
{
set_item_count(10);
}
};
#define TEST_HJ_DUMP_GET_HASH_AREA_SIZE() (get_hash_area_size())
#define TEST_HJ_DUMP_SET_HASH_AREA_SIZE(size) (set_hash_area_size(size))
class ObHashJoinDumpTest : public blocksstable::TestDataFilePrepare, public ::testing::WithParamInterface<ObJoinType> {
public:
ObHashJoinDumpTest()
: blocksstable::TestDataFilePrepare("TestDiskIR", 2 << 20, 5000),
hash_join_(alloc_),
merge_join_(alloc_),
hash_plan_(hash_join_, alloc_),
merge_plan_(merge_join_, alloc_)
{}
virtual void SetUp() override
{
ASSERT_EQ(OB_SUCCESS, init_tenant_mgr());
blocksstable::TestDataFilePrepare::SetUp();
GCONF.enable_sql_operator_dump.set_value("True");
ObHashJoin::HJ_PROCESSOR_ALGO =
ObHashJoin::ENABLE_HJ_NEST_LOOP | ObHashJoin::ENABLE_HJ_RECURSIVE | ObHashJoin::ENABLE_HJ_IN_MEMORY;
}
virtual void TearDown() override
{
blocksstable::TestDataFilePrepare::TearDown();
destroy_tenant_mgr();
ObHashJoin::HJ_PROCESSOR_ALGO = 0;
}
int init_tenant_mgr();
void destroy_tenant_mgr()
{
ObTenantManager::get_instance().destroy();
}
int64_t get_hash_area_size()
{
int64_t hash_area_size = 0;
int ret = OB_SUCCESS;
ret = ObSqlWorkareaUtil::get_workarea_size(HASH_WORK_AREA, OB_SYS_TENANT_ID, hash_area_size);
if (OB_FAIL(ret)) {
LOG_WARN("failed to get hash area size", K(ret), K(hash_area_size));
}
return hash_area_size;
}
void set_hash_area_size(int64_t size)
{
int ret = OB_SUCCESS;
int64_t tenant_id = OB_SYS_TENANT_ID;
ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
if (tenant_config.is_valid()) {
tenant_config->_hash_area_size = size;
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected status: config is invalid", K(tenant_id));
}
// ASSERT_EQ(OB_SUCCESS, ret);
}
void setup_test(ObJoinType join_type, int32_t string_size, int64_t left_row_count, bool left_reverse,
JoinDataGenerator::IdxCntFunc left_func, int64_t right_row_count, bool right_reverse,
JoinDataGenerator::IdxCntFunc right_func);
// iterate hash join result and verify result with merge join.
void run_test(int64_t print_row_cnt = 0);
protected:
struct JoinPlan {
explicit JoinPlan(ObJoin& join, ObIAllocator& alloc) : join_(join), left_(alloc), right_(alloc), expr_(alloc)
{}
int setup_plan(ObJoinType join_type);
ObSQLSessionInfo session_;
ObPhysicalPlan plan_;
ObExecContext exec_ctx_;
ObJoin& join_;
JoinDataGenerator left_;
JoinDataGenerator right_;
MockSqlExpression expr_;
};
ObArenaAllocator alloc_;
ObHashJoin hash_join_;
ObMergeJoin merge_join_;
JoinPlan hash_plan_;
JoinPlan merge_plan_;
};
int ObHashJoinDumpTest::JoinPlan::setup_plan(ObJoinType join_type)
{
int ret = OB_SUCCESS;
left_.set_id(0);
right_.set_id(1);
join_.set_id(2);
join_.set_column_count(JoinDataGenerator::CELL_CNT * (join_type < LEFT_SEMI_JOIN ? 2 : 1));
left_.set_phy_plan(&plan_);
right_.set_phy_plan(&plan_);
join_.set_phy_plan(&plan_);
if (NULL != dynamic_cast<ObMergeJoin*>(&join_) && (RIGHT_SEMI_JOIN == join_type || RIGHT_ANTI_JOIN == join_type)) {
// right semi and right anti join not supported for merge join,
// convert to left semi/anti join.
if (OB_FAIL(join_.set_child(0, right_))) {
} else if (OB_FAIL(join_.set_child(1, left_))) {
} else if (OB_FAIL(join_.set_join_type((ObJoinType)(join_type - 1)))) {
}
} else {
if (OB_FAIL(join_.set_child(0, left_))) {
} else if (OB_FAIL(join_.set_child(1, right_))) {
} else if (OB_FAIL(join_.set_join_type(join_type))) {
}
}
// setup equal condition
ObPostExprItem c1;
ObPostExprItem c2;
ObPostExprItem op;
ObExprResType res_type;
res_type.set_calc_type(ObIntType);
c1.set_column(0);
c2.set_column(JoinDataGenerator::CELL_CNT);
op.set_op(plan_.get_allocator(), "=", 2);
op.get_expr_operator()->set_result_type(res_type);
if (OB_FAIL(ret)) {
} else if (OB_FAIL(expr_.add_expr_item(c1))) {
} else if (OB_FAIL(expr_.add_expr_item(c2))) {
} else if (OB_FAIL(expr_.add_expr_item(op))) {
} else if (OB_FAIL(join_.add_equijoin_condition(&expr_))) {
}
// setup context
ObString tenant_name("test");
if (OB_FAIL(ret)) {
} else if (OB_FAIL(session_.test_init(0, 0, 0, NULL))) {
} else if (OB_FAIL(ObPreProcessSysVars::init_sys_var())) {
} else if (OB_FAIL(session_.load_default_sys_variable(false, true))) {
} else if (OB_FAIL(session_.init_tenant(tenant_name, OB_SYS_TENANT_ID))) {
} else if (OB_FAIL(exec_ctx_.init_phy_op(3))) {
} else if (OB_FAIL(exec_ctx_.create_physical_plan_ctx())) {
} else {
exec_ctx_.set_my_session(&session_);
}
return ret;
}
void ObHashJoinDumpTest::setup_test(ObJoinType join_type, int32_t string_size, int64_t left_row_count,
bool left_reverse, JoinDataGenerator::IdxCntFunc left_func, int64_t right_row_count, bool right_reverse,
JoinDataGenerator::IdxCntFunc right_func)
{
JoinPlan* plans[] = {&hash_plan_, &merge_plan_};
for (int i = 0; i < 2; i++) {
auto& plan = *plans[i];
ASSERT_EQ(OB_SUCCESS, plan.setup_plan(join_type));
plan.left_.row_cnt_ = left_row_count;
plan.right_.row_cnt_ = right_row_count;
plan.left_.string_size_ = string_size;
plan.right_.string_size_ = string_size;
if (&plan != &merge_plan_) {
plan.left_.reverse_ = left_reverse;
plan.right_.reverse_ = right_reverse;
}
plan.left_.idx_cnt_func_ = left_func;
plan.right_.idx_cnt_func_ = right_func;
ASSERT_EQ(OB_SUCCESS, plan.left_.test_init());
ASSERT_EQ(OB_SUCCESS, plan.right_.test_init());
}
ObSEArray<ObOrderDirection, 1> directions;
directions.push_back(NULLS_FIRST_ASC);
ASSERT_EQ(OB_SUCCESS, merge_join_.set_merge_directions(directions));
}
void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
{
ObArenaAllocator alloc;
typedef ObArray<int64_t*> ResArray;
int64_t res_cell_cnt = JoinDataGenerator::CELL_CNT * 2;
auto fun = [&](JoinPlan& plan, ResArray& res) -> void {
ASSERT_EQ(OB_SUCCESS, plan.join_.open(plan.exec_ctx_));
int ret = OB_SUCCESS;
const ObNewRow* row = NULL;
int64_t cnt = 0;
while (OB_SUCC(ret)) {
if (OB_FAIL(plan.join_.get_next_row(plan.exec_ctx_, row))) {
ASSERT_EQ(OB_ITER_END, ret);
} else {
if (cnt < print_row_cnt) {
LOG_INFO("join res", K(*row));
}
auto r = static_cast<int64_t*>(alloc.alloc(sizeof(int64_t) * res_cell_cnt));
ASSERT_TRUE(NULL != r);
for (int64_t i = 0; i < res_cell_cnt; i++) {
auto& c = row->cells_[i];
if (i < row->count_ && c.get_type() == ObIntType) {
r[i] = c.get_int();
} else {
r[i] = -1;
}
}
ASSERT_EQ(OB_SUCCESS, res.push_back(r));
}
cnt++;
}
};
auto pfunc = [&](int64_t* r) {
ObSqlString s;
for (int64_t i = 0; i < res_cell_cnt; i++) {
s.append_fmt("%ld, ", r[i]);
}
LOG_INFO("RES:", K(s.ptr()));
};
ResArray hash_res;
fun(hash_plan_, hash_res);
ASSERT_FALSE(HasFatalFailure());
ResArray merge_res;
fun(merge_plan_, merge_res);
ASSERT_FALSE(HasFatalFailure());
ASSERT_EQ(hash_res.count(), merge_res.count());
auto sort_cmp = [&](int64_t* l, int64_t* r) {
for (int64_t i = 0; i < res_cell_cnt; i++) {
if (l[i] != r[i]) {
return l[i] < r[i];
}
}
return false;
};
std::sort(&hash_res.at(0), &hash_res.at(0) + hash_res.count(), sort_cmp);
std::sort(&merge_res.at(0), &merge_res.at(0) + merge_res.count(), sort_cmp);
for (int64_t i = 0; i < hash_res.count(); i++) {
if (sort_cmp(hash_res.at(i), merge_res.at(i)) || sort_cmp(merge_res.at(i), hash_res.at(i))) {
pfunc(hash_res.at(i));
pfunc(merge_res.at(i));
ASSERT_FALSE(true);
}
}
hash_join_.close(hash_plan_.exec_ctx_);
merge_join_.close(merge_plan_.exec_ctx_);
}
TEST_P(ObHashJoinDumpTest, inmemory)
{
setup_test(
GetParam(),
512,
1000,
false,
[](int64_t id, int64_t) { return id % 3 == 0 ? 1 : 0; },
1000,
false,
[](int64_t id, int64_t) { return id % 5 == 0 ? 1 : 0; });
ASSERT_FALSE(HasFatalFailure());
run_test();
ASSERT_FALSE(HasFatalFailure());
}
TEST_P(ObHashJoinDumpTest, disk)
{
setup_test(
GetParam(),
2000,
200000 * 3,
false,
[](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
200000 * 5,
false,
[](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
ASSERT_FALSE(HasFatalFailure());
run_test();
ASSERT_FALSE(HasFatalFailure());
}
TEST_P(ObHashJoinDumpTest, disk_reverse)
{
setup_test(
GetParam(),
1999,
200000 * 3,
true,
[](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
200000 * 5,
false,
[](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
ASSERT_FALSE(HasFatalFailure());
run_test();
ASSERT_FALSE(HasFatalFailure());
}
INSTANTIATE_TEST_CASE_P(join, ObHashJoinDumpTest,
::testing::Values(INNER_JOIN, LEFT_OUTER_JOIN, RIGHT_OUTER_JOIN, FULL_OUTER_JOIN, LEFT_SEMI_JOIN, RIGHT_SEMI_JOIN,
LEFT_ANTI_JOIN, RIGHT_ANTI_JOIN));
TEST_F(ObHashJoinDumpTest, test_recursion)
{
auto part_cnt_bak = ObHashJoin::PART_COUNT;
auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
ObHashJoin::PART_COUNT = 5;
ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
setup_test(
RIGHT_OUTER_JOIN,
2000,
200000 * 3,
false,
[](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
200000 * 5,
false,
[](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
ASSERT_FALSE(HasFatalFailure());
run_test(10);
ASSERT_FALSE(HasFatalFailure());
ObHashJoin::PART_COUNT = part_cnt_bak;
ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
}
// TEST_F(ObHashJoinDumpTest, test_right_outer_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_OUTER_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_left_outer_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(LEFT_OUTER_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_left_semi)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(LEFT_SEMI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_left_anti)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(LEFT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_right_semi_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_SEMI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_right_anti_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_run_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// int64_t algo = ObHashJoin::HJ_PROCESSOR_ALGO;
// ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_RECURSIVE;
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 200000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// ObHashJoin::HJ_PROCESSOR_ALGO = algo;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_run_nest_loop)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// int64_t algo = ObHashJoin::HJ_PROCESSOR_ALGO;
// ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_NEST_LOOP;
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 300000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// ObHashJoin::HJ_PROCESSOR_ALGO = algo;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_run_nest_loop_to_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// bool pre_nest_loop_to_recursive = ObHashJoin::TEST_NEST_LOOP_TO_RECURSIVE;
// ObHashJoin::TEST_NEST_LOOP_TO_RECURSIVE = true;
// int64_t algo = ObHashJoin::HJ_PROCESSOR_ALGO;
// ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_NEST_LOOP;
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 300000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// ObHashJoin::TEST_NEST_LOOP_TO_RECURSIVE = pre_nest_loop_to_recursive;
// pre_nest_loop_to_recursive = ObHashJoin::TEST_NEST_LOOP_TO_RECURSIVE;
// ASSERT_EQ(false, pre_nest_loop_to_recursive);
// ObHashJoin::HJ_PROCESSOR_ALGO = algo;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_run_in_memory)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// int64_t algo = ObHashJoin::HJ_PROCESSOR_ALGO;
// ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_IN_MEMORY;
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 300000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// ObHashJoin::HJ_PROCESSOR_ALGO = algo;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_in_memory)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(RIGHT_ANTI_JOIN, 2000,
// 100000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 2000000 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_bigger_left)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(LEFT_OUTER_JOIN, 2000,
// 2000000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 2 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
// TEST_F(ObHashJoinDumpTest, test_bigger_left_using_recursive)
// {
// int64_t hash_mem = 0;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ(100 * 1024 * 1024, hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(20* 1024 * 1024);
// int64_t algo = ObHashJoin::HJ_PROCESSOR_ALGO;
// ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_RECURSIVE;
// auto part_cnt_bak = ObHashJoin::PART_COUNT;
// auto page_cnt_bak = ObHashJoin::MAX_PAGE_COUNT;
// ObHashJoin::PART_COUNT = 5;
// ObHashJoin::MAX_PAGE_COUNT = (20L << 20) / OB_MALLOC_MIDDLE_BLOCK_SIZE; // 20MB memory
// setup_test(LEFT_OUTER_JOIN, 2000,
// 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
// 2 * 5, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
// ASSERT_FALSE(HasFatalFailure());
// run_test(10);
// ASSERT_FALSE(HasFatalFailure());
// ObHashJoin::HJ_PROCESSOR_ALGO = algo;
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((20 * 1024 * 1024), hash_mem);
// TEST_HJ_DUMP_SET_HASH_AREA_SIZE(100* 1024 * 1024);
// hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
// ASSERT_EQ((100 * 1024 * 1024), hash_mem);
// ObHashJoin::PART_COUNT = part_cnt_bak;
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
// }
TEST_F(ObHashJoinDumpTest, test_bad_case)
{
setup_test(
INNER_JOIN,
2000,
1,
false,
[](int64_t, int64_t) { return 400000; },
200000,
false,
[](int64_t, int64_t) { return 2; });
ASSERT_FALSE(HasFatalFailure());
run_test(10);
ASSERT_FALSE(HasFatalFailure());
}
TEST_F(ObHashJoinDumpTest, test_right_join)
{
setup_test(
RIGHT_SEMI_JOIN,
2000,
1,
false,
[](int64_t, int64_t) { return 400000; },
200000,
false,
[](int64_t, int64_t) { return 2; });
ASSERT_FALSE(HasFatalFailure());
run_test(10);
ASSERT_FALSE(HasFatalFailure());
}
TEST_F(ObHashJoinDumpTest, test_anti_right_join)
{
setup_test(
RIGHT_ANTI_JOIN,
2000,
1,
false,
[](int64_t, int64_t) { return 400000; },
200000,
false,
[](int64_t, int64_t) { return 2; });
ASSERT_FALSE(HasFatalFailure());
run_test(10);
ASSERT_FALSE(HasFatalFailure());
}
TEST_F(ObHashJoinDumpTest, test_file_leak)
{
int ret = OB_SUCCESS;
setup_test(
INNER_JOIN,
2000,
200000 * 3,
false,
[](int64_t id, int64_t) { return id % 3 == 0 ? 2 : 0; },
200000 * 5,
false,
[](int64_t id, int64_t) { return id % 5 == 0 ? 2 : 0; });
ASSERT_FALSE(HasFatalFailure());
hash_plan_.left_.iter_end_ret_ = OB_ERR_SYS;
hash_plan_.right_.iter_end_ret_ = OB_ERR_SYS;
ASSERT_EQ(OB_SUCCESS, hash_join_.open(hash_plan_.exec_ctx_));
const ObNewRow* row = NULL;
while (OB_SUCC(hash_join_.get_next_row(hash_plan_.exec_ctx_, row))) {}
ASSERT_EQ(OB_ERR_SYS, ret);
hash_join_.close(hash_plan_.exec_ctx_);
}
TEST_F(ObHashJoinDumpTest, test_conf)
{
int64_t hash_mem = 0;
hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
ASSERT_EQ(100 * 1024 * 1024, hash_mem);
TEST_HJ_DUMP_SET_HASH_AREA_SIZE(1024 * 1024 * 1024);
hash_mem = TEST_HJ_DUMP_GET_HASH_AREA_SIZE();
ASSERT_EQ((1024 * 1024 * 1024), hash_mem);
}
int ObHashJoinDumpTest::init_tenant_mgr()
{
int ret = OB_SUCCESS;
ObTenantManager& tm = ObTenantManager::get_instance();
ObAddr self;
oceanbase::rpc::frame::ObReqTransport req_transport(NULL, NULL);
oceanbase::obrpc::ObSrvRpcProxy rpc_proxy;
oceanbase::obrpc::ObCommonRpcProxy rs_rpc_proxy;
oceanbase::share::ObRsMgr rs_mgr;
int64_t tenant_id = OB_SYS_TENANT_ID;
self.set_ip_addr("127.0.0.1", 8086);
ret = ObTenantConfigMgr::get_instance().add_tenant_config(tenant_id);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.init(self, rpc_proxy, rs_rpc_proxy, rs_mgr, &req_transport, &ObServerConfig::get_instance());
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(tenant_id);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.set_tenant_mem_limit(tenant_id, 2L * 1024L * 1024L * 1024L, 4L * 1024L * 1024L * 1024L);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(OB_SYS_TENANT_ID);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(OB_SERVER_TENANT_ID);
EXPECT_EQ(OB_SUCCESS, ret);
const int64_t ulmt = 128LL << 30;
const int64_t llmt = 128LL << 30;
ret = tm.set_tenant_mem_limit(OB_SYS_TENANT_ID, ulmt, llmt);
EXPECT_EQ(OB_SUCCESS, ret);
oceanbase::lib::set_memory_limit(128LL << 32);
return ret;
}
} // namespace sql
} // namespace oceanbase
int main(int argc, char** argv)
{
oceanbase::sql::init_sql_factories();
OB_LOGGER.set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
OB_LOGGER.disable();
return ret;
}