patch 4.0
This commit is contained in:
@ -1,9 +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)
|
||||
#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)
|
||||
|
||||
@ -17,9 +17,12 @@
|
||||
#include "sql/engine/ob_phy_operator.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class JoinDataGenerator : public ObPhyOperator {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
class JoinDataGenerator : public ObPhyOperator
|
||||
{
|
||||
public:
|
||||
const static int64_t CELL_CNT = 4;
|
||||
|
||||
@ -30,50 +33,32 @@ public:
|
||||
|
||||
const static int64_t INT_VARCHAR_BUF_SIZE = 10;
|
||||
|
||||
class Ctx : public ObPhyOperatorCtx {
|
||||
class Ctx : public ObPhyOperatorCtx
|
||||
{
|
||||
public:
|
||||
Ctx(ObExecContext& c) : ObPhyOperatorCtx(c)
|
||||
{}
|
||||
virtual void destroy()
|
||||
{
|
||||
return ObPhyOperatorCtx::destroy_base();
|
||||
}
|
||||
Ctx(ObExecContext &c) : ObPhyOperatorCtx(c) {}
|
||||
virtual void destroy() { return ObPhyOperatorCtx::destroy_base(); }
|
||||
};
|
||||
|
||||
explicit JoinDataGenerator(common::ObIAllocator& alloc) : ObPhyOperator(alloc)
|
||||
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;
|
||||
}
|
||||
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_;
|
||||
delete []str_;
|
||||
str_ = NULL;
|
||||
}
|
||||
if (projector_) {
|
||||
delete[] projector_;
|
||||
delete []projector_;
|
||||
projector_ = NULL;
|
||||
}
|
||||
}
|
||||
@ -82,16 +67,16 @@ public:
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
row_id_ = 0;
|
||||
if (reverse_) {
|
||||
row_id_ = row_cnt_ - 1;
|
||||
}
|
||||
@ -104,13 +89,13 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual int init_op_ctx(ObExecContext& ec) const override
|
||||
virtual int init_op_ctx(ObExecContext &ec) const override
|
||||
{
|
||||
Ctx* ctx = NULL;
|
||||
Ctx *ctx = NULL;
|
||||
return CREATE_PHY_OPERATOR_CTX(Ctx, ec, get_id(), get_type(), ctx);
|
||||
}
|
||||
|
||||
virtual int inner_open(ObExecContext& ec) const override
|
||||
virtual int inner_open(ObExecContext &ec) const override
|
||||
{
|
||||
return init_op_ctx(ec);
|
||||
}
|
||||
@ -122,7 +107,7 @@ public:
|
||||
idx_cnt_ = 0;
|
||||
}
|
||||
|
||||
virtual int get_next_row(ObExecContext&, const common::ObNewRow*& row) const override
|
||||
virtual int get_next_row(ObExecContext &, const common::ObNewRow *&row) const override
|
||||
{
|
||||
while (true) {
|
||||
if (row_id_ < 0 || row_id_ >= row_cnt_) {
|
||||
@ -150,19 +135,22 @@ public:
|
||||
|
||||
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};
|
||||
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]};
|
||||
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]);
|
||||
// '0' flag ignored with precision and ‘%d’ gnu_printf format
|
||||
snprintf(bufs[i], INT_VARCHAR_BUF_SIZE, "%.*ld", (int)INT_VARCHAR_BUF_SIZE, ints[i]);
|
||||
objs[i]->set_varchar(bufs[i], INT_VARCHAR_BUF_SIZE);
|
||||
}
|
||||
}
|
||||
@ -187,11 +175,11 @@ private:
|
||||
mutable int64_t row_id_ = 0;
|
||||
mutable int64_t idx_ = 0;
|
||||
mutable int64_t idx_cnt_ = 0;
|
||||
mutable char* str_ = NULL;
|
||||
mutable char *str_ = NULL;
|
||||
mutable char int_varchar_buf_[CELL_CNT * INT_VARCHAR_BUF_SIZE];
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
} // end sql
|
||||
} // end oceanbase
|
||||
|
||||
#endif // OCEANBASE_JOIN_JOIN_DATA_GENERATOR_H_
|
||||
#endif // OCEANBASE_JOIN_JOIN_DATA_GENERATOR_H_
|
||||
|
||||
435
unittest/sql/engine/join/ob_blk_nested_loop_join_test.cpp
Normal file
435
unittest/sql/engine/join/ob_blk_nested_loop_join_test.cpp
Normal file
@ -0,0 +1,435 @@
|
||||
/**
|
||||
* 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 "sql/engine/join/ob_block_based_nested_loop_join.h"
|
||||
#include "lib/utility/ob_test_util.h"
|
||||
#include "lib/utility/ob_tracepoint.h"
|
||||
#include "sql/ob_sql_init.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/expr/ob_expr_equal.h"
|
||||
#include "sql/engine/expr/ob_expr_mod.h"
|
||||
#include "ob_join_fake_table.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 ObBLKNestedLoopJoinTest : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
ObBLKNestedLoopJoinTest();
|
||||
virtual ~ObBLKNestedLoopJoinTest();
|
||||
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);
|
||||
ObBLKNestedLoopJoinTest(const ObBLKNestedLoopJoinTest &other);
|
||||
ObBLKNestedLoopJoinTest& operator=(const ObBLKNestedLoopJoinTest &other);
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
class ObBLKNestedLoopJoinPlan
|
||||
{
|
||||
public:
|
||||
static ObBLKNestedLoopJoin &get_instance()
|
||||
{
|
||||
return blk_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;
|
||||
if (OB_FAIL(left_op_.init(BNL_JOIN_TEST))) {
|
||||
SQL_ENG_LOG(WARN, "left op init failed", K(ret));
|
||||
} else if (OB_FAIL(right_op_.init(BNL_JOIN_TEST))) {
|
||||
SQL_ENG_LOG(WARN, "right op init failed", K(ret));
|
||||
} else if (OB_FAIL(out_data_.init(BNL_JOIN_TEST))) {
|
||||
SQL_ENG_LOG(WARN, "out data init failed", K(ret));
|
||||
} else {
|
||||
blk_nested_loop_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);
|
||||
if (OB_FAIL(blk_nested_loop_join_.set_child(0, left_op_))) {
|
||||
SQL_ENG_LOG(WARN, "set child failed", K(ret));
|
||||
} else if (OB_FAIL(blk_nested_loop_join_.set_child(1, right_op_))) {
|
||||
SQL_ENG_LOG(WARN, "set child failed", K(ret));
|
||||
} else if (OB_FAIL(blk_nested_loop_join_.set_join_type(join_type))) {} else if (OB_FAIL(init_equal_conds())) {
|
||||
SQL_ENG_LOG(WARN, "set join type failed", K(ret));
|
||||
} else if (OB_FAIL(init_other_conds())) {
|
||||
SQL_ENG_LOG(WARN, "init other conds", K(ret));
|
||||
} else if (OB_FAIL(left_op_.prepare_data(case_id, TT_LEFT_TABLE, join_type))) {
|
||||
SQL_ENG_LOG(WARN, "left op prepare data failed", K(ret));
|
||||
} else if (OB_FAIL(right_op_.prepare_data(case_id, TT_RIGHT_TABLE, join_type))) {
|
||||
SQL_ENG_LOG(WARN, "right op prepare data failed", K(ret));
|
||||
} else if (OB_FAIL(out_data_.prepare_data(case_id, TT_OUT_TABLE, join_type))) {
|
||||
SQL_ENG_LOG(WARN, "out data prepare data failed", K(ret));
|
||||
}
|
||||
}
|
||||
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);
|
||||
blk_nested_loop_join_.reuse();
|
||||
left_op_.reuse();
|
||||
right_op_.reuse();
|
||||
out_data_.reuse();
|
||||
allocator_.reuse();
|
||||
}
|
||||
private:
|
||||
static void set_id()
|
||||
{
|
||||
blk_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)
|
||||
{
|
||||
blk_nested_loop_join_.set_column_count(2 * input_column_count);
|
||||
left_op_.set_column_count(input_column_count);
|
||||
left_projector_[0] = 0;
|
||||
left_projector_[1] = 1;
|
||||
left_op_.set_projector(left_projector_, 2);
|
||||
right_op_.set_column_count(input_column_count);
|
||||
right_projector_[0] = 0;
|
||||
right_projector_[1] = 1;
|
||||
right_op_.set_projector(right_projector_, 2);
|
||||
out_data_.set_column_count(2 * input_column_count);
|
||||
out_projector_[0] = 0;
|
||||
out_projector_[1] = 1;
|
||||
out_projector_[2] = 2;
|
||||
out_projector_[3] = 3;
|
||||
out_data_.set_projector(out_projector_, 4);
|
||||
}
|
||||
static int init_equal_conds()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// like t1.a = t2.b => (t1.a, t2.b, OP_EQ)
|
||||
ObPostExprItem item_col_left;
|
||||
ObPostExprItem item_col_right;
|
||||
ObPostExprItem item_op;
|
||||
ObExprResType cmp_type;
|
||||
cmp_type.set_type(ObIntType);
|
||||
cmp_type.set_calc_type(ObIntType);
|
||||
|
||||
int64_t idx = 1;
|
||||
int64_t column_count = 2;
|
||||
for (idx = 0; OB_SUCC(ret) && idx < column_count; ++idx) {
|
||||
item_col_left.set_column(idx);
|
||||
item_col_right.set_column(idx + column_count);
|
||||
item_op.set_op(phy_plan_.get_allocator(), "=", 2);
|
||||
item_op.get_expr_operator()->set_result_type(cmp_type);
|
||||
if (OB_FAIL(equal_expr_[idx].add_expr_item(item_col_left))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(equal_expr_[idx].add_expr_item(item_col_right))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(equal_expr_[idx].add_expr_item(item_op))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(blk_nested_loop_join_.add_other_join_condition(&equal_expr_[idx]))) {
|
||||
SQL_ENG_LOG(WARN, "add equal join condition failed", K(ret));
|
||||
}
|
||||
}
|
||||
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 column_count = 2;
|
||||
// int64_t cond_count = 1;
|
||||
ObPostExprItem item_col_left;
|
||||
ObPostExprItem item_col_right;
|
||||
ObPostExprItem item_op_add;
|
||||
ObPostExprItem item_int;
|
||||
ObPostExprItem item_op_gt;
|
||||
ObExprResType add_type;
|
||||
add_type.set_type(ObIntType);
|
||||
add_type.set_calc_type(ObIntType);
|
||||
ObExprResType cmp_type;
|
||||
cmp_type.set_type(ObIntType);
|
||||
cmp_type.set_calc_type(ObIntType);
|
||||
|
||||
item_col_left.set_column(0);
|
||||
item_col_right.set_column(0 + column_count);
|
||||
item_op_add.set_op(phy_plan_.get_allocator(), "+", 2);
|
||||
item_op_add.get_expr_operator()->set_result_type(add_type);
|
||||
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(add_type);
|
||||
if (OB_FAIL(other_expr_[0].add_expr_item(item_col_left))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(other_expr_[0].add_expr_item(item_col_right))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(other_expr_[0].add_expr_item(item_op_add))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(other_expr_[0].add_expr_item(item_int))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(other_expr_[0].add_expr_item(item_op_gt))) {
|
||||
SQL_ENG_LOG(WARN, "add expr item failed", K(ret));
|
||||
} else if (OB_FAIL(blk_nested_loop_join_.add_other_join_condition(&other_expr_[0]))) {
|
||||
SQL_ENG_LOG(WARN, "add equal join condition failed", K(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
ObBLKNestedLoopJoinPlan();
|
||||
public:
|
||||
static ObPhysicalPlan phy_plan_;
|
||||
static MockSqlExpression equal_expr_[2];
|
||||
static MockSqlExpression other_expr_[2];
|
||||
static ObBLKNestedLoopJoin blk_nested_loop_join_;
|
||||
static ObJoinFakeTable left_op_;
|
||||
static ObJoinFakeTable right_op_;
|
||||
static ObJoinFakeTable out_data_;
|
||||
static ObArenaAllocator allocator_;
|
||||
static int32 left_projector_[10];
|
||||
static int32 right_projector_[10];
|
||||
static int32 out_projector_[10];
|
||||
};
|
||||
|
||||
ObPhysicalPlan ObBLKNestedLoopJoinPlan::phy_plan_;
|
||||
MockSqlExpression ObBLKNestedLoopJoinPlan::equal_expr_[2];
|
||||
MockSqlExpression ObBLKNestedLoopJoinPlan::other_expr_[2];
|
||||
ObBLKNestedLoopJoin ObBLKNestedLoopJoinPlan::blk_nested_loop_join_(ObBLKNestedLoopJoinPlan::phy_plan_.get_allocator());
|
||||
ObJoinFakeTable ObBLKNestedLoopJoinPlan::left_op_;
|
||||
ObJoinFakeTable ObBLKNestedLoopJoinPlan::right_op_;
|
||||
ObJoinFakeTable ObBLKNestedLoopJoinPlan::out_data_;
|
||||
ObArenaAllocator ObBLKNestedLoopJoinPlan::allocator_(ObModIds::OB_PAGE_ARENA);
|
||||
int32 ObBLKNestedLoopJoinPlan::left_projector_[10];
|
||||
int32 ObBLKNestedLoopJoinPlan::right_projector_[10];
|
||||
int32 ObBLKNestedLoopJoinPlan::out_projector_[10];
|
||||
|
||||
ObBLKNestedLoopJoinTest::ObBLKNestedLoopJoinTest()
|
||||
{
|
||||
}
|
||||
|
||||
ObBLKNestedLoopJoinTest::~ObBLKNestedLoopJoinTest()
|
||||
{
|
||||
}
|
||||
|
||||
void ObBLKNestedLoopJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
{
|
||||
ASSERT_EQ(OB_SUCCESS, ObBLKNestedLoopJoinPlan::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());
|
||||
ASSERT_EQ(OB_SUCCESS, create_test_session(exec_ctx));
|
||||
auto my_session = exec_ctx.get_my_session();
|
||||
ASSERT_FALSE(NULL == my_session );
|
||||
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
|
||||
my_session->load_default_sys_variable(false, false);
|
||||
|
||||
ObBLKNestedLoopJoin &blk_nested_loop_join = ObBLKNestedLoopJoinPlan::get_instance();
|
||||
ASSERT_EQ(OB_SUCCESS, blk_nested_loop_join.open(exec_ctx));
|
||||
ObJoinFakeTable &out_data = ObBLKNestedLoopJoinPlan::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 = blk_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, blk_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, blk_nested_loop_join.close(exec_ctx));
|
||||
ASSERT_EQ(OB_SUCCESS, out_data.close(exec_ctx));
|
||||
} END_THREAD_CODE(join_test);
|
||||
ObBLKNestedLoopJoinPlan::reuse();
|
||||
}
|
||||
|
||||
void ObBLKNestedLoopJoinTest::serialize_test()
|
||||
{
|
||||
ObBLKNestedLoopJoin &blk_nested_loop_join_1 = ObBLKNestedLoopJoinPlan::get_instance();
|
||||
ObBLKNestedLoopJoin blk_nested_loop_join_2(ObBLKNestedLoopJoinPlan::phy_plan_.get_allocator());
|
||||
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
|
||||
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
|
||||
ASSERT_EQ(OB_SUCCESS, ObBLKNestedLoopJoinPlan::init(0, INNER_JOIN));
|
||||
|
||||
int64_t pos = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, blk_nested_loop_join_1.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos));
|
||||
ASSERT_EQ(pos, blk_nested_loop_join_1.get_serialize_size());
|
||||
int64_t data_len = pos;
|
||||
|
||||
blk_nested_loop_join_2.set_phy_plan(const_cast<ObPhysicalPlan *>(blk_nested_loop_join_1.get_phy_plan()));
|
||||
pos = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, blk_nested_loop_join_2.deserialize(buf, data_len, pos));
|
||||
ASSERT_EQ(pos, data_len);
|
||||
const char *str_1 = to_cstring(blk_nested_loop_join_1);
|
||||
const char *str_2 = to_cstring(blk_nested_loop_join_2);
|
||||
ASSERT_EQ(0, strcmp(str_1, str_2));
|
||||
|
||||
ObBLKNestedLoopJoinPlan::reuse();
|
||||
}
|
||||
|
||||
void ObBLKNestedLoopJoinTest::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());
|
||||
ObBLKNestedLoopJoin &blk_nested_loop_join = ObBLKNestedLoopJoinPlan::get_instance();
|
||||
|
||||
if (OB_FAIL(ObBLKNestedLoopJoinPlan::init(0, LEFT_OUTER_JOIN))) {
|
||||
SQL_ENG_LOG(WARN, "init bnl join plan failed", K(ret));
|
||||
} else if (OB_FAIL(blk_nested_loop_join.open(exec_ctx))) {
|
||||
SQL_ENG_LOG(WARN, "open bnl join plan failed", K(ret));
|
||||
} else {
|
||||
while (OB_SUCC(ret)) {
|
||||
ret = blk_nested_loop_join.get_next_row(exec_ctx, row);
|
||||
}
|
||||
if (OB_ITER_END == ret) {
|
||||
ret = blk_nested_loop_join.close(exec_ctx);
|
||||
}
|
||||
}
|
||||
ObBLKNestedLoopJoinPlan::reuse();
|
||||
if (OB_FAIL(ret)) {
|
||||
ASSERT_EQ(expect_ret, ret);
|
||||
}
|
||||
}
|
||||
|
||||
void ObBLKNestedLoopJoinTest::serialize_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObBLKNestedLoopJoin &blk_nested_loop_join = ObBLKNestedLoopJoinPlan::get_instance();
|
||||
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
|
||||
char buf[MAX_SERIALIZE_BUF_LEN] = {'\0'};
|
||||
ASSERT_EQ(OB_SUCCESS, ObBLKNestedLoopJoinPlan::init(0, INNER_JOIN));
|
||||
|
||||
int64_t pos = 0;
|
||||
if (OB_FAIL(blk_nested_loop_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {
|
||||
SQL_ENG_LOG(WARN, "serialize bnl join plan failed", K(ret));
|
||||
} else {
|
||||
int64_t data_len = pos;
|
||||
pos = 0;
|
||||
ObBLKNestedLoopJoinPlan::reuse();
|
||||
blk_nested_loop_join.set_phy_plan(ObBLKNestedLoopJoinPlan::get_phy_plan());
|
||||
if (OB_FAIL(blk_nested_loop_join.deserialize(buf, data_len, pos))) {
|
||||
SQL_ENG_LOG(WARN, "deserialize bnl join plan failed", K(ret));
|
||||
}
|
||||
}
|
||||
ObBLKNestedLoopJoinPlan::reuse();
|
||||
if (OB_FAIL(ret)) {
|
||||
ASSERT_EQ(expect_ret, ret);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_0)
|
||||
{
|
||||
join_test(0, INNER_JOIN);
|
||||
join_test(0, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_1)
|
||||
{
|
||||
join_test(1, INNER_JOIN);
|
||||
join_test(1, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_2)
|
||||
{
|
||||
join_test(2, INNER_JOIN);
|
||||
join_test(2, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_3)
|
||||
{
|
||||
join_test(3, INNER_JOIN);
|
||||
join_test(3, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_4)
|
||||
{
|
||||
join_test(4, INNER_JOIN);
|
||||
join_test(4, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
TEST_F(ObBLKNestedLoopJoinTest, join_case_5)
|
||||
{
|
||||
join_test(5, INNER_JOIN);
|
||||
join_test(5, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
init_sql_factories();
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
OB_LOGGER.disable();
|
||||
return ret;
|
||||
}
|
||||
@ -11,8 +11,8 @@
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define private public
|
||||
#define protected public
|
||||
#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"
|
||||
@ -27,27 +27,28 @@
|
||||
#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 {
|
||||
class MockSqlExpression : public ObSqlExpression
|
||||
{
|
||||
public:
|
||||
MockSqlExpression() : ObSqlExpression(alloc_)
|
||||
MockSqlExpression(): ObSqlExpression(alloc_)
|
||||
{
|
||||
set_item_count(10);
|
||||
}
|
||||
~MockSqlExpression()
|
||||
{}
|
||||
~MockSqlExpression() {}
|
||||
};
|
||||
|
||||
class ObHashJoinTest : public ::testing::Test {
|
||||
class ObHashJoinTest: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
ObHashJoinTest();
|
||||
virtual ~ObHashJoinTest();
|
||||
|
||||
protected:
|
||||
void join_test(int64_t case_id, ObJoinType join_type);
|
||||
void serialize_test();
|
||||
@ -55,24 +56,24 @@ protected:
|
||||
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);
|
||||
|
||||
ObHashJoinTest(const ObHashJoinTest &other);
|
||||
ObHashJoinTest& operator=(const ObHashJoinTest &other);
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
class ObHashJoinPlan {
|
||||
class ObHashJoinPlan
|
||||
{
|
||||
public:
|
||||
static ObHashJoin& get_instance()
|
||||
static ObHashJoin &get_instance()
|
||||
{
|
||||
return hash_join_;
|
||||
}
|
||||
static ObJoinFakeTable& get_out_data()
|
||||
static ObJoinFakeTable &get_out_data()
|
||||
{
|
||||
return out_data_;
|
||||
}
|
||||
static ObPhysicalPlan* get_phy_plan()
|
||||
static ObPhysicalPlan *get_phy_plan()
|
||||
{
|
||||
return &phy_plan_;
|
||||
}
|
||||
@ -89,7 +90,7 @@ public:
|
||||
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
|
||||
left_op_.set_rows(10000); // default
|
||||
out_data_.set_phy_plan(&phy_plan_);
|
||||
set_id();
|
||||
set_column_count(2);
|
||||
@ -98,16 +99,15 @@ public:
|
||||
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))) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -128,7 +128,6 @@ public:
|
||||
out_data_.reuse();
|
||||
allocator_.reuse();
|
||||
}
|
||||
|
||||
private:
|
||||
static void set_id()
|
||||
{
|
||||
@ -159,11 +158,10 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -190,20 +188,17 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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];
|
||||
@ -229,10 +224,12 @@ 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)
|
||||
{
|
||||
@ -249,15 +246,15 @@ void ObHashJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
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();
|
||||
ObHashJoin &hash_join = ObHashJoinPlan::get_instance();
|
||||
ASSERT_EQ(OB_SUCCESS, hash_join.open(exec_ctx));
|
||||
ObJoinFakeTable& out_data = ObHashJoinPlan::get_out_data();
|
||||
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;
|
||||
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) {
|
||||
@ -267,21 +264,21 @@ void ObHashJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
|
||||
ASSERT_EQ(join_ret, out_ret);
|
||||
if (OB_SUCCESS == join_ret && OB_SUCCESS == out_ret) {
|
||||
ObObj* join_cells = join_row->cells_;
|
||||
ObObj *join_cells = join_row->cells_;
|
||||
std::vector<int64_t> res;
|
||||
res.resize(4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
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++) {
|
||||
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) {
|
||||
} // 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);
|
||||
@ -309,7 +306,7 @@ void ObHashJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
|
||||
void ObHashJoinTest::serialize_test()
|
||||
{
|
||||
ObHashJoin& hash_join_1 = ObHashJoinPlan::get_instance();
|
||||
ObHashJoin &hash_join_1 = ObHashJoinPlan::get_instance();
|
||||
ObArenaAllocator alloc;
|
||||
ObHashJoin hash_join_2(alloc);
|
||||
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
|
||||
@ -321,12 +318,12 @@ void ObHashJoinTest::serialize_test()
|
||||
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()));
|
||||
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);
|
||||
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();
|
||||
@ -336,15 +333,15 @@ void ObHashJoinTest::join_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExecContext exec_ctx;
|
||||
const ObNewRow* row = NULL;
|
||||
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();
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
@ -361,14 +358,14 @@ void ObHashJoinTest::join_exception_test(int expect_ret)
|
||||
void ObHashJoinTest::serialize_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObHashJoin& hash_join = ObHashJoinPlan::get_instance();
|
||||
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 {
|
||||
if (OB_FAIL(hash_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {}
|
||||
else {
|
||||
int64_t data_len = pos;
|
||||
pos = 0;
|
||||
ObHashJoinPlan::reuse();
|
||||
@ -395,11 +392,10 @@ void ObHashJoinTest::memlimit_exception_test(int expect_ret, int64_t memsize)
|
||||
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, 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);
|
||||
ret = hash_join.open(exec_ctx);
|
||||
ObHashJoinPlan::reuse();
|
||||
// need remote condition
|
||||
if (OB_FAIL(ret)) {
|
||||
@ -457,29 +453,29 @@ TEST_F(ObHashJoinTest, join_case_5)
|
||||
|
||||
TEST_F(ObHashJoinTest, memlimit_test)
|
||||
{
|
||||
memlimit_exception_test(OB_ALLOCATE_MEMORY_FAILED, 100 * 1024 * 1024);
|
||||
memlimit_exception_test(OB_SUCCESS, 100 * 1024 * 1024);
|
||||
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); \
|
||||
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); \
|
||||
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)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
init_sql_factories();
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
OB_LOGGER.disable();
|
||||
return ret;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,13 +18,22 @@
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/ob_sql_define.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
namespace test {
|
||||
enum TableType { TT_UNKNOWN, TT_LEFT_TABLE, TT_RIGHT_TABLE, TT_OUT_TABLE };
|
||||
namespace sql
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
enum TableType {
|
||||
TT_UNKNOWN,
|
||||
TT_LEFT_TABLE,
|
||||
TT_RIGHT_TABLE,
|
||||
TT_OUT_TABLE
|
||||
};
|
||||
|
||||
enum JoinOpTestType {
|
||||
enum JoinOpTestType
|
||||
{
|
||||
MERGE_JOIN_TEST,
|
||||
NL_JOIN_TEST,
|
||||
BNL_JOIN_TEST,
|
||||
@ -42,28 +51,20 @@ typedef struct {
|
||||
int64_t out_full_[DATA_COUNT * DATA_COUNT][4];
|
||||
} JoinData;
|
||||
|
||||
class ObQueryRangeDummy {
|
||||
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_;
|
||||
}
|
||||
|
||||
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 {
|
||||
class ObJoinFakeTableScanInput : public ObIPhyOperatorInput
|
||||
{
|
||||
public:
|
||||
virtual int init(ObExecContext& ctx, ObTaskInfo& task_info, ObPhyOperator& op)
|
||||
virtual int init(ObExecContext &ctx, ObTaskInfo &task_info, ObPhyOperator &op)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
UNUSED(task_info);
|
||||
@ -76,7 +77,7 @@ public:
|
||||
return PHY_TABLE_SCAN;
|
||||
}
|
||||
|
||||
ObQueryRangeDummy& get_query_range()
|
||||
ObQueryRangeDummy &get_query_range()
|
||||
{
|
||||
return query_range_;
|
||||
}
|
||||
@ -85,55 +86,40 @@ private:
|
||||
ObQueryRangeDummy query_range_;
|
||||
};
|
||||
static ObArenaAllocator alloc_;
|
||||
class ObJoinFakeTable : public ObPhyOperator {
|
||||
class ObJoinFakeTable: public ObPhyOperator
|
||||
{
|
||||
protected:
|
||||
class ObJoinFakeTableCtx : public ObPhyOperatorCtx {
|
||||
class ObJoinFakeTableCtx: public ObPhyOperatorCtx
|
||||
{
|
||||
friend class ObJoinFakeTable;
|
||||
|
||||
public:
|
||||
ObJoinFakeTableCtx(ObExecContext& exex_ctx) : ObPhyOperatorCtx(exex_ctx), iter_(0)
|
||||
{}
|
||||
virtual void destroy()
|
||||
{
|
||||
return ObPhyOperatorCtx::destroy_base();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
@ -143,8 +129,8 @@ private:
|
||||
bool is_inited_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
} // namespace test
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif /* OB_JOIN_FAKE_TABLE_H_ */
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
|
||||
#include "lib/utility/ob_test_util.h"
|
||||
#include <gtest/gtest.h>
|
||||
#define private public
|
||||
#define protected public
|
||||
#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"
|
||||
@ -31,45 +31,45 @@ using namespace oceanbase::sql::test;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::observer;
|
||||
using namespace oceanbase::share;
|
||||
class MockSqlExpression : public ObSqlExpression {
|
||||
class MockSqlExpression : public ObSqlExpression
|
||||
{
|
||||
public:
|
||||
MockSqlExpression() : ObSqlExpression(alloc_)
|
||||
MockSqlExpression(): ObSqlExpression(alloc_)
|
||||
{
|
||||
set_item_count(10);
|
||||
}
|
||||
~MockSqlExpression()
|
||||
{}
|
||||
~MockSqlExpression() {}
|
||||
};
|
||||
|
||||
class ObMergeJoinTest : public ::testing::Test {
|
||||
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);
|
||||
|
||||
ObMergeJoinTest(const ObMergeJoinTest &other);
|
||||
ObMergeJoinTest& operator=(const ObMergeJoinTest &other);
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
class ObMergeJoinPlan {
|
||||
class ObMergeJoinPlan
|
||||
{
|
||||
public:
|
||||
static ObMergeJoin& get_instance()
|
||||
static ObMergeJoin &get_instance()
|
||||
{
|
||||
return merge_join_;
|
||||
}
|
||||
static ObJoinFakeTable& get_out_data()
|
||||
static ObJoinFakeTable &get_out_data()
|
||||
{
|
||||
return out_data_;
|
||||
}
|
||||
static ObPhysicalPlan* get_phy_plan()
|
||||
static ObPhysicalPlan *get_phy_plan()
|
||||
{
|
||||
return &phy_plan_;
|
||||
}
|
||||
@ -99,17 +99,16 @@ public:
|
||||
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))) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -130,7 +129,6 @@ public:
|
||||
out_data_.reuse();
|
||||
allocator_.reuse();
|
||||
}
|
||||
|
||||
private:
|
||||
static void set_id()
|
||||
{
|
||||
@ -161,11 +159,10 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -192,20 +189,17 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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];
|
||||
@ -231,10 +225,12 @@ 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)
|
||||
{
|
||||
@ -252,27 +248,27 @@ void ObMergeJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
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();
|
||||
ObMergeJoin &merge_join = ObMergeJoinPlan::get_instance();
|
||||
ASSERT_EQ(OB_SUCCESS, merge_join.open(exec_ctx));
|
||||
ObJoinFakeTable& out_data = ObMergeJoinPlan::get_out_data();
|
||||
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;
|
||||
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_;
|
||||
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_;
|
||||
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();
|
||||
@ -282,7 +278,7 @@ void ObMergeJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
ASSERT_EQ(join_cell2, out_cell2);
|
||||
ASSERT_EQ(join_cell3, out_cell3);
|
||||
}
|
||||
} // while
|
||||
} // 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));
|
||||
@ -295,7 +291,7 @@ void ObMergeJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
|
||||
void ObMergeJoinTest::serialize_test()
|
||||
{
|
||||
ObMergeJoin& merge_join_1 = ObMergeJoinPlan::get_instance();
|
||||
ObMergeJoin &merge_join_1 = ObMergeJoinPlan::get_instance();
|
||||
ObArenaAllocator alloc;
|
||||
ObMergeJoin merge_join_2(alloc);
|
||||
const int64_t MAX_SERIALIZE_BUF_LEN = 1024;
|
||||
@ -307,12 +303,12 @@ void ObMergeJoinTest::serialize_test()
|
||||
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()));
|
||||
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);
|
||||
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();
|
||||
@ -322,15 +318,15 @@ void ObMergeJoinTest::join_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExecContext exec_ctx;
|
||||
const ObNewRow* row = NULL;
|
||||
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();
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
@ -347,14 +343,14 @@ void ObMergeJoinTest::join_exception_test(int expect_ret)
|
||||
void ObMergeJoinTest::serialize_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMergeJoin& merge_join = ObMergeJoinPlan::get_instance();
|
||||
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 {
|
||||
if (OB_FAIL(merge_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {}
|
||||
else {
|
||||
int64_t data_len = pos;
|
||||
pos = 0;
|
||||
ObMergeJoinPlan::reuse();
|
||||
@ -415,19 +411,19 @@ TEST_F(ObMergeJoinTest, join_case_5)
|
||||
join_test(5, FULL_OUTER_JOIN);
|
||||
}
|
||||
|
||||
// TEST_F(ObMergeJoinTest, serialize_case_0)
|
||||
//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); \
|
||||
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)
|
||||
//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);
|
||||
@ -467,7 +463,7 @@ TEST_F(ObMergeJoinTest, join_case_5)
|
||||
// JOIN_EXCEPTION_TEST("ob_merge_join.cpp", "trans_to_fill_cache", "t5", OB_ERROR, OB_ERROR);
|
||||
//}
|
||||
//
|
||||
// TEST_F(ObMergeJoinTest, join_exception_1)
|
||||
//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);
|
||||
@ -485,13 +481,13 @@ TEST_F(ObMergeJoinTest, join_case_5)
|
||||
//}
|
||||
|
||||
#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); \
|
||||
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)
|
||||
//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);
|
||||
@ -509,12 +505,12 @@ TEST_F(ObMergeJoinTest, join_case_5)
|
||||
// SERIALIZE_EXCEPTION_TEST("ob_join.cpp", "deserialize", "t17", OB_ERROR, OB_ERROR);
|
||||
//}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
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);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
OB_LOGGER.disable();
|
||||
return ret;
|
||||
|
||||
@ -23,35 +23,35 @@ using namespace oceanbase::sql;
|
||||
using namespace oceanbase::sql::test;
|
||||
using namespace oceanbase::common;
|
||||
|
||||
class ObNestedLoopJoinTest : public ::testing::Test {
|
||||
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);
|
||||
|
||||
ObNestedLoopJoinTest(const ObNestedLoopJoinTest &other);
|
||||
ObNestedLoopJoinTest& operator=(const ObNestedLoopJoinTest &other);
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
class ObNestedLoopJoinPlan {
|
||||
class ObNestedLoopJoinPlan
|
||||
{
|
||||
public:
|
||||
static ObNestedLoopJoin& get_instance()
|
||||
static ObNestedLoopJoin &get_instance()
|
||||
{
|
||||
return nested_loop_join_;
|
||||
}
|
||||
static ObJoinFakeTable& get_out_data()
|
||||
static ObJoinFakeTable &get_out_data()
|
||||
{
|
||||
return out_data_;
|
||||
}
|
||||
static ObPhysicalPlan* get_phy_plan()
|
||||
static ObPhysicalPlan *get_phy_plan()
|
||||
{
|
||||
return &phy_plan_;
|
||||
}
|
||||
@ -62,16 +62,15 @@ public:
|
||||
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))) {
|
||||
}
|
||||
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()
|
||||
@ -87,7 +86,6 @@ public:
|
||||
out_data_.reuse();
|
||||
allocator_.reuse();
|
||||
}
|
||||
|
||||
private:
|
||||
static void set_id()
|
||||
{
|
||||
@ -119,11 +117,10 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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()
|
||||
@ -141,20 +138,17 @@ private:
|
||||
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]))) {
|
||||
}
|
||||
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];
|
||||
@ -178,41 +172,42 @@ 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)
|
||||
{
|
||||
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();
|
||||
ObNestedLoopJoin &nested_loop_join = ObNestedLoopJoinPlan::get_instance();
|
||||
ASSERT_EQ(OB_SUCCESS, nested_loop_join.open(exec_ctx));
|
||||
ObJoinFakeTable& out_data = ObNestedLoopJoinPlan::get_out_data();
|
||||
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;
|
||||
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_;
|
||||
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_;
|
||||
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();
|
||||
@ -222,21 +217,20 @@ void ObNestedLoopJoinTest::join_test(int64_t case_id, ObJoinType join_type)
|
||||
ASSERT_EQ(join_cell2, out_cell2);
|
||||
ASSERT_EQ(join_cell3, out_cell3);
|
||||
}
|
||||
} // while
|
||||
} // 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);
|
||||
} END_THREAD_CODE(join_test);
|
||||
ObNestedLoopJoinPlan::reuse();
|
||||
}
|
||||
|
||||
void ObNestedLoopJoinTest::serialize_test()
|
||||
{
|
||||
ObNestedLoopJoin& nested_loop_join_1 = ObNestedLoopJoinPlan::get_instance();
|
||||
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'};
|
||||
@ -247,12 +241,12 @@ void ObNestedLoopJoinTest::serialize_test()
|
||||
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()));
|
||||
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);
|
||||
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();
|
||||
@ -262,15 +256,15 @@ void ObNestedLoopJoinTest::join_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExecContext exec_ctx;
|
||||
const ObNewRow* row = NULL;
|
||||
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();
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
@ -287,14 +281,14 @@ void ObNestedLoopJoinTest::join_exception_test(int expect_ret)
|
||||
void ObNestedLoopJoinTest::serialize_exception_test(int expect_ret)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObNestedLoopJoin& nested_loop_join = ObNestedLoopJoinPlan::get_instance();
|
||||
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 {
|
||||
if (OB_FAIL(nested_loop_join.serialize(buf, MAX_SERIALIZE_BUF_LEN, pos))) {}
|
||||
else {
|
||||
int64_t data_len = pos;
|
||||
pos = 0;
|
||||
ObNestedLoopJoinPlan::reuse();
|
||||
@ -343,19 +337,19 @@ TEST_F(ObNestedLoopJoinTest, join_case_5)
|
||||
join_test(5, LEFT_OUTER_JOIN);
|
||||
}
|
||||
|
||||
// TEST_F(ObNestedLoopJoinTest, serialize_case_0)
|
||||
//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); \
|
||||
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)
|
||||
//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);
|
||||
@ -378,7 +372,7 @@ TEST_F(ObNestedLoopJoinTest, join_case_5)
|
||||
// JOIN_EXCEPTION_TEST("ob_nested_loop_join.cpp", "calc_right_query_range", "t5", 1, OB_NOT_INIT);
|
||||
//}
|
||||
//
|
||||
// TEST_F(ObNestedLoopJoinTest, join_exception_1)
|
||||
//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);
|
||||
@ -395,13 +389,13 @@ TEST_F(ObNestedLoopJoinTest, join_case_5)
|
||||
//}
|
||||
|
||||
#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); \
|
||||
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)
|
||||
//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);
|
||||
@ -423,9 +417,9 @@ TEST_F(ObNestedLoopJoinTest, join_case_5)
|
||||
// SERIALIZE_EXCEPTION_TEST("ob_nested_loop_join.cpp", "deserialize", "t3", OB_ERROR, OB_ERROR);
|
||||
//}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
init_sql_factories();
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
94
unittest/sql/engine/join/ob_nested_loop_join_test2.cpp
Normal file
94
unittest/sql/engine/join/ob_nested_loop_join_test2.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 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 <gtest/gtest.h>
|
||||
#include "lib/utility/ob_test_util.h"
|
||||
#include "sql/ob_sql_init.h"
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::sql;
|
||||
class TestNLJTest2: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
TestNLJTest2();
|
||||
virtual ~TestNLJTest2();
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(TestNLJTest2);
|
||||
protected:
|
||||
// function members
|
||||
protected:
|
||||
// data members
|
||||
};
|
||||
|
||||
TestNLJTest2::TestNLJTest2()
|
||||
{
|
||||
}
|
||||
|
||||
TestNLJTest2::~TestNLJTest2()
|
||||
{
|
||||
}
|
||||
|
||||
void TestNLJTest2::SetUp()
|
||||
{
|
||||
}
|
||||
|
||||
void TestNLJTest2::TearDown()
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(TestNLJTest2, serialize_rescan_params)
|
||||
{
|
||||
ObPhysicalPlan phy_plan;
|
||||
ObNestedLoopJoin join(phy_plan.get_allocator());
|
||||
join.set_phy_plan(&phy_plan);
|
||||
join.set_id(100);
|
||||
join.set_column_count(111);
|
||||
join.init_param_count(200);
|
||||
ObSqlExpressionFactory factory(phy_plan.get_allocator());
|
||||
ObSqlExpression *expr = NULL;
|
||||
ASSERT_EQ(OB_SUCCESS, factory.alloc(expr));
|
||||
ASSERT_TRUE(NULL != expr);
|
||||
ObPostExprItem item;
|
||||
expr->set_item_count(1);
|
||||
ASSERT_EQ(OB_SUCCESS, item.set_column(10));
|
||||
ASSERT_EQ(OB_SUCCESS, expr->add_expr_item(item));
|
||||
ASSERT_EQ(OB_SUCCESS, join.add_nlj_param(expr, 3));
|
||||
COMMON_LOG(INFO, "join", K(join));
|
||||
// serialize
|
||||
char buf[1024];
|
||||
int64_t pos = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, join.serialize(buf, 1024, pos));
|
||||
ASSERT_EQ(pos, join.get_serialize_size());
|
||||
const char* join_str = S(join);
|
||||
// deserialize
|
||||
int64_t data_len = pos;
|
||||
pos = 0;
|
||||
ObPhysicalPlan phy_plan2;
|
||||
ObNestedLoopJoin join2(phy_plan2.get_allocator());
|
||||
join2.set_phy_plan(&phy_plan2);
|
||||
ASSERT_EQ(OB_SUCCESS, join2.deserialize(buf, data_len, pos));
|
||||
ASSERT_EQ(data_len, pos);
|
||||
COMMON_LOG(INFO, "join2", K(join2));
|
||||
const char* join2_str = S(join2);
|
||||
ASSERT_STREQ(join_str, join2_str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
init_sql_factories();
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -25,16 +25,21 @@
|
||||
#include "sql/ob_sql_init.h"
|
||||
#include "sql/engine/ob_sql_mem_mgr_processor.h"
|
||||
#include "observer/omt/ob_tenant_config_mgr.h"
|
||||
#include "share/ob_simple_mem_limit_getter.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
using namespace omt;
|
||||
static ObSimpleMemLimitGetter getter;
|
||||
|
||||
class MockSqlExpression : public ObSqlExpression {
|
||||
class MockSqlExpression : public ObSqlExpression
|
||||
{
|
||||
public:
|
||||
MockSqlExpression(ObIAllocator& alloc) : ObSqlExpression(alloc)
|
||||
MockSqlExpression(ObIAllocator &alloc): ObSqlExpression(alloc)
|
||||
{
|
||||
set_item_count(10);
|
||||
}
|
||||
@ -43,23 +48,24 @@ public:
|
||||
#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> {
|
||||
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_)
|
||||
{}
|
||||
: blocksstable::TestDataFilePrepare(&getter, "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;
|
||||
ObHashJoin::HJ_PROCESSOR_ALGO = ObHashJoin::ENABLE_HJ_NEST_LOOP
|
||||
| ObHashJoin::ENABLE_HJ_RECURSIVE
|
||||
| ObHashJoin::ENABLE_HJ_IN_MEMORY;
|
||||
}
|
||||
virtual void TearDown() override
|
||||
{
|
||||
@ -70,7 +76,6 @@ public:
|
||||
int init_tenant_mgr();
|
||||
void destroy_tenant_mgr()
|
||||
{
|
||||
ObTenantManager::get_instance().destroy();
|
||||
}
|
||||
|
||||
int64_t get_hash_area_size()
|
||||
@ -98,24 +103,25 @@ public:
|
||||
// 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);
|
||||
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)
|
||||
{}
|
||||
struct JoinPlan
|
||||
{
|
||||
explicit JoinPlan(ObJoin &join, ObIAllocator &alloc)
|
||||
: exec_ctx_(alloc), join_(join), left_(alloc), right_(alloc), expr_(alloc) {}
|
||||
|
||||
int setup_plan(ObJoinType join_type);
|
||||
|
||||
ObSQLSessionInfo session_;
|
||||
ObPhysicalPlan plan_;
|
||||
ObExecContext exec_ctx_;
|
||||
ObJoin& join_;
|
||||
ObJoin &join_;
|
||||
JoinDataGenerator left_;
|
||||
JoinDataGenerator right_;
|
||||
MockSqlExpression expr_;
|
||||
@ -143,7 +149,8 @@ int ObHashJoinDumpTest::JoinPlan::setup_plan(ObJoinType join_type)
|
||||
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)) {
|
||||
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_))) {
|
||||
@ -191,13 +198,13 @@ int ObHashJoinDumpTest::JoinPlan::setup_plan(ObJoinType join_type)
|
||||
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)
|
||||
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_};
|
||||
JoinPlan *plans[] = { &hash_plan_, &merge_plan_ };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& plan = *plans[i];
|
||||
auto &plan = *plans[i];
|
||||
ASSERT_EQ(OB_SUCCESS, plan.setup_plan(join_type));
|
||||
|
||||
plan.left_.row_cnt_ = left_row_count;
|
||||
@ -223,12 +230,13 @@ void ObHashJoinDumpTest::setup_test(ObJoinType join_type, int32_t string_size, i
|
||||
void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
{
|
||||
ObArenaAllocator alloc;
|
||||
typedef ObArray<int64_t*> ResArray;
|
||||
typedef ObArray<int64_t *> ResArray;
|
||||
int64_t res_cell_cnt = JoinDataGenerator::CELL_CNT * 2;
|
||||
auto fun = [&](JoinPlan& plan, ResArray& res) -> void {
|
||||
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;
|
||||
const ObNewRow *row = NULL;
|
||||
int64_t cnt = 0;
|
||||
while (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(plan.join_.get_next_row(plan.exec_ctx_, row))) {
|
||||
@ -237,10 +245,10 @@ void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
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));
|
||||
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];
|
||||
auto &c = row->cells_[i];
|
||||
if (i < row->count_ && c.get_type() == ObIntType) {
|
||||
r[i] = c.get_int();
|
||||
} else {
|
||||
@ -253,7 +261,8 @@ void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
}
|
||||
};
|
||||
|
||||
auto pfunc = [&](int64_t* r) {
|
||||
auto pfunc = [&](int64_t *r)
|
||||
{
|
||||
ObSqlString s;
|
||||
for (int64_t i = 0; i < res_cell_cnt; i++) {
|
||||
s.append_fmt("%ld, ", r[i]);
|
||||
@ -269,7 +278,8 @@ void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
ASSERT_FALSE(HasFatalFailure());
|
||||
|
||||
ASSERT_EQ(hash_res.count(), merge_res.count());
|
||||
auto sort_cmp = [&](int64_t* l, int64_t* r) {
|
||||
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];
|
||||
@ -280,7 +290,8 @@ void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
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))) {
|
||||
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);
|
||||
@ -293,15 +304,9 @@ void ObHashJoinDumpTest::run_test(int64_t print_row_cnt)
|
||||
|
||||
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; });
|
||||
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());
|
||||
@ -309,15 +314,9 @@ TEST_P(ObHashJoinDumpTest, inmemory)
|
||||
|
||||
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; });
|
||||
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());
|
||||
@ -325,39 +324,33 @@ TEST_P(ObHashJoinDumpTest, disk)
|
||||
|
||||
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; });
|
||||
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));
|
||||
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; });
|
||||
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());
|
||||
@ -366,6 +359,7 @@ TEST_F(ObHashJoinDumpTest, test_recursion)
|
||||
ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
|
||||
}
|
||||
|
||||
//暂时屏蔽掉这些case,否则farm时间太长,但如果修改join,请打开线下跑下这些test case
|
||||
// TEST_F(ObHashJoinDumpTest, test_right_outer_recursive)
|
||||
// {
|
||||
// int64_t hash_mem = 0;
|
||||
@ -445,6 +439,7 @@ TEST_F(ObHashJoinDumpTest, test_recursion)
|
||||
// ObHashJoin::MAX_PAGE_COUNT = page_cnt_bak;
|
||||
// }
|
||||
|
||||
|
||||
// TEST_F(ObHashJoinDumpTest, test_left_anti)
|
||||
// {
|
||||
// int64_t hash_mem = 0;
|
||||
@ -724,15 +719,9 @@ TEST_F(ObHashJoinDumpTest, test_recursion)
|
||||
|
||||
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; });
|
||||
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());
|
||||
@ -740,15 +729,9 @@ TEST_F(ObHashJoinDumpTest, test_bad_case)
|
||||
|
||||
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; });
|
||||
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());
|
||||
@ -756,38 +739,28 @@ TEST_F(ObHashJoinDumpTest, test_right_join)
|
||||
|
||||
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; });
|
||||
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());
|
||||
}
|
||||
|
||||
// see https://aone.alibaba-inc.com/project/81079/issue/17944328
|
||||
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; });
|
||||
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))) {}
|
||||
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_);
|
||||
}
|
||||
@ -806,7 +779,6 @@ TEST_F(ObHashJoinDumpTest, test_conf)
|
||||
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;
|
||||
@ -816,32 +788,27 @@ int ObHashJoinDumpTest::init_tenant_mgr()
|
||||
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);
|
||||
ret = getter.add_tenant(tenant_id,
|
||||
2L * 1024L * 1024L * 1024L, 4L * 1024L * 1024L * 1024L);
|
||||
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);
|
||||
ret = getter.add_tenant(OB_SERVER_TENANT_ID,
|
||||
ulmt,
|
||||
llmt);
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
oceanbase::lib::set_memory_limit(128LL << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
} // end sql
|
||||
} // end oceanbase
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
oceanbase::sql::init_sql_factories();
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
OB_LOGGER.disable();
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user