/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #define USING_LOG_PREFIX SQL #include #define private public #define protected public #include "sql/engine/set/ob_merge_union_op.h" #include "sql/engine/set/ob_merge_intersect_op.h" #include "sql/engine/set/ob_merge_except_op.h" #include "sql/engine/aggregate/ob_merge_distinct_op.h" #include "share/system_variable/ob_system_variable.h" #include "storage/blocksstable/ob_data_file_prepare.h" #include "sql/engine/table/ob_fake_table.h" #include "set_data_op_generator.h" #include "sql/ob_sql_init.h" #include "share/ob_cluster_version.h" #include "observer/omt/ob_tenant_config_mgr.h" #include "share/datum/ob_datum_funcs.h" namespace oceanbase { namespace sql { using namespace common; using namespace share; using namespace omt; ObArenaAllocator allocator_; ObExecContext exec_ctx_(allocator_); ObEvalCtx op_eval_ctx_ = ObEvalCtx(exec_ctx_); class MockSqlExpression : public ObSqlExpression { public: MockSqlExpression(ObIAllocator &alloc): ObSqlExpression(alloc) { set_item_count(10); } }; #define TEST_SET_DUMP_GET_HASH_AREA_SIZE() (get_hash_area_size()) #define TEST_SET_DUMP_SET_HASH_AREA_SIZE(size) (set_hash_area_size(size)) const int64_t BATCH_SIZE = 256; class ObMergeSetVecTest: public blocksstable::TestDataFilePrepare, public ::testing::WithParamInterface { public: typedef std::function IdxCntFunc; enum TestAlgo { UNION = 0, INTERSECT, EXCEPT, DISTINCT }; protected: struct SetPlan { explicit SetPlan(ObExecContext &exec_ctx, const ObOpSpec &left_spec, const ObOpSpec &right_spec, ObOpInput *input) : set_op_(nullptr), left_(exec_ctx, left_spec, input, ObString("LEFT_OP")), right_(exec_ctx, right_spec, input, ObString("RIGHT_OP")), expr_(exec_ctx.get_allocator()) { } int setup_plan(ObOperator *set_op); ObSQLSessionInfo session_; ObPhysicalPlan plan_; ObOperator *set_op_; SetDataGeneratorOp left_; SetDataGeneratorOp right_; MockSqlExpression expr_; }; public: ObMergeSetVecTest() : blocksstable::TestDataFilePrepare("TestDiskIR", 8<<20, 5000), spec1_(exec_ctx_.get_allocator(), PHY_MERGE_INTERSECT), spec2_(exec_ctx_.get_allocator(), PHY_MERGE_INTERSECT), spec3_(exec_ctx_.get_allocator(), PHY_MERGE_EXCEPT), spec4_(exec_ctx_.get_allocator(), PHY_MERGE_EXCEPT), spec5_(exec_ctx_.get_allocator(), PHY_TABLE_SCAN), spec6_(exec_ctx_.get_allocator(), PHY_TABLE_SCAN), spec7_(exec_ctx_.get_allocator(), PHY_MERGE_UNION), spec8_(exec_ctx_.get_allocator(), PHY_MERGE_UNION), spec9_(exec_ctx_.get_allocator(), PHY_TABLE_SCAN), spec10_(exec_ctx_.get_allocator(), PHY_TABLE_SCAN), spec11_(exec_ctx_.get_allocator(), PHY_MERGE_DISTINCT), spec12_(exec_ctx_.get_allocator(), PHY_MERGE_DISTINCT), merge_intersect_vec_(exec_ctx_, spec1_, nullptr), merge_intersect_(exec_ctx_, spec2_, nullptr), merge_except_vec_(exec_ctx_, spec3_, nullptr), merge_except_(exec_ctx_, spec4_, nullptr), merge_union_vec_(exec_ctx_, spec7_, nullptr), merge_union_(exec_ctx_, spec8_, nullptr), merge_distinct_vec_(exec_ctx_, spec11_, nullptr), merge_distinct_(exec_ctx_, spec12_, nullptr), merge_set_op_vec_(nullptr), merge_set_op_(nullptr), merge_plan_vec_(exec_ctx_, spec5_, spec6_, nullptr), merge_plan_(exec_ctx_, spec9_, spec10_, nullptr) { spec1_.batch_size_ = BATCH_SIZE; spec2_.batch_size_ = 0; spec3_.batch_size_ = BATCH_SIZE; spec4_.batch_size_ = 0; spec5_.batch_size_ = BATCH_SIZE; spec6_.batch_size_ = BATCH_SIZE; spec7_.batch_size_ = BATCH_SIZE; spec8_.batch_size_ = 0; spec9_.batch_size_ = 0; spec10_.batch_size_ = 0; spec11_.batch_size_ = BATCH_SIZE; spec12_.batch_size_ = 0; } int init_tenant_mgr(); virtual void SetUp() override { ASSERT_EQ(OB_SUCCESS, init_tenant_mgr()); blocksstable::TestDataFilePrepare::SetUp(); ASSERT_EQ(OB_SUCCESS, blocksstable::ObTmpFileManager::get_instance().init()); CHUNK_MGR.set_limit(128L * 1024L * 1024L * 1024L); GCONF.enable_sql_operator_dump.set_value("True"); uint64_t cluster_version = CLUSTER_VERSION_3000; common::ObClusterVersion::get_instance().update_cluster_version(cluster_version); EXPECT_EQ(cluster_version, common::ObClusterVersion::get_instance().get_cluster_version()); LOG_INFO("set cluster version", K(cluster_version), K(common::ObClusterVersion::get_instance().get_cluster_version())); } virtual void TearDown() override { blocksstable::ObTmpFileManager::get_instance().destroy(); blocksstable::TestDataFilePrepare::TearDown(); destroy_tenant_mgr(); } void destroy_tenant_mgr() { ObTenantManager::get_instance().destroy(); } int64_t get_hash_area_size() { int64_t hash_area_size = 0; int ret = OB_SUCCESS; ret = ObSqlWorkareaUtil::get_workarea_size(HASH_WORK_AREA, OB_SYS_TENANT_ID, hash_area_size); if (OB_FAIL(ret)) { LOG_WARN("failed to get hash area size", K(ret), K(hash_area_size)); } return hash_area_size; } void set_hash_area_size(int64_t size) { int ret = OB_SUCCESS; int64_t tenant_id = OB_SYS_TENANT_ID; ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); if (tenant_config.is_valid()) { tenant_config->_hash_area_size = size; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected status: config is invalid", K(tenant_id)); } // ASSERT_EQ(OB_SUCCESS, ret); } void setup_plan(SetPlan &plan, bool vec_algo, ObMergeSetVecTest::TestAlgo algo); void setup_test(TestAlgo algo, int32_t string_size, int64_t left_row_count, bool left_reverse, IdxCntFunc left_func, int64_t right_row_count, bool right_reverse, IdxCntFunc right_func); // iterate hash join result and verify result with merge join. void run_test(int64_t print_row_cnt = 0); int generate_merge_set_spec(ObMergeSetSpec &spec, bool is_vec) { int ret = OB_SUCCESS; //spec.set_exprs_.set_allocator(&alloc_); //spec.sort_cmp_funs_.set_allocator(&alloc_); //spec.sort_collations_.set_allocator(&alloc_); spec.set_exprs_.destroy(); spec.cost_ = 1; spec.rows_ = 5000; spec.width_ = 20; spec.is_distinct_ = true; if (OB_FAIL(spec.output_.init(3))) { LOG_WARN("failed to init output_", K(ret)); return ret; } int pos1 = is_vec ? 2000000 : 5000000; for (int i = 0; i < 3 ; ++i) { ObExpr *expr = static_cast (alloc_.alloc(sizeof(ObExpr))); if (OB_FAIL(spec.output_.push_back(expr))) { LOG_WARN("failed to push back expr", K(ret)); return ret; } expr->batch_result_ = is_vec; expr->batch_idx_mask_ = (expr->batch_result_ ? UINT64_MAX : 0); expr->eval_batch_func_ = nullptr; expr->eval_func_ = nullptr; expr->frame_idx_ = 0; expr->datum_off_ = pos1; pos1 += sizeof(ObDatum) * op_eval_ctx_.max_batch_size_; expr->eval_info_off_ = pos1; pos1 += sizeof(ObEvalInfo); expr->eval_flags_off_ = pos1; pos1 += ObBitVector::memory_size(op_eval_ctx_.max_batch_size_); expr->pvt_skip_off_ = pos1; ObDatum *datums = expr->locate_batch_datums(op_eval_ctx_); for (int64_t j = 0; j < op_eval_ctx_.max_batch_size_; j++) { datums[j].ptr_ = op_eval_ctx_.frames_[0] + pos1; pos1 += (3 == i ? 522 : 8); } } if (OB_FAIL(spec.set_exprs_.init(3))) { LOG_WARN("failed to get output exprs", K(ret), K(spec.set_exprs_.capacity_)); return ret; } pos1 = is_vec ? 6000000 : 7000000; for (int i = 0; i < 3; ++i) { ObExpr *expr = static_cast(alloc_.alloc(sizeof(ObExpr)));//新建expr, 设置expr对应的datum, 在对应位置放置datum if (OB_FAIL(spec.set_exprs_.push_back(expr))) { return ret; } //expr->batch_result_ = (spec.batch_size_ > 0); //expr->batch_idx_mask_ = (expr->batch_result_ ? UINT64_MAX : 0); expr->eval_batch_func_ = nullptr; expr->eval_func_ = nullptr; expr->frame_idx_ = 0; expr->datum_off_ = pos1; pos1 += sizeof(ObDatum) * op_eval_ctx_.max_batch_size_; expr->eval_info_off_ = pos1; pos1 += sizeof(ObEvalInfo); expr->eval_flags_off_ = pos1; pos1 += ObBitVector::memory_size(op_eval_ctx_.max_batch_size_); expr->pvt_skip_off_ = pos1; ObDatum *datums = expr->locate_batch_datums(op_eval_ctx_); for (int64_t j = 0; j < op_eval_ctx_.max_batch_size_; j++) { datums[j].ptr_ = op_eval_ctx_.frames_[0] + pos1; pos1 += (3 == i ? 522 : 8); } } if (OB_FAIL(spec.sort_collations_.init(1))) { LOG_WARN("failed to init sort collations", K(ret)); } else if (OB_FAIL(spec.sort_cmp_funs_.init(1))) { LOG_WARN("failed to compare function", K(ret)); } else { LOG_WARN("init funcs"); // 初始化compare func和hash func ObOrderDirection order_direction = default_asc_direction(); bool is_ascending = is_ascending_direction(order_direction); ObSortFieldCollation field_collation(0, CS_TYPE_BINARY, is_ascending, (is_null_first(order_direction) ^ is_ascending) ? NULL_LAST : NULL_FIRST); if (OB_FAIL(spec.sort_collations_.push_back(field_collation))) { LOG_WARN("failed to push back sort collation", K(ret)); } ObSortCmpFunc cmp_func; ObObjType tmp_type = ObIntType; cmp_func.cmp_func_ = ObDatumFuncs::get_nullsafe_cmp_func(tmp_type, tmp_type, field_collation.null_pos_, field_collation.cs_type_, SCALE_UNKNOWN_YET, lib::is_oracle_mode(), false); if (OB_FAIL(spec.sort_cmp_funs_.push_back(cmp_func))) { LOG_WARN("failed to push back sort function", K(ret)); } } return ret; } int generate_merge_distinct_spec(ObMergeDistinctSpec &spec, bool is_vec) { int ret = OB_SUCCESS; //spec.set_exprs_.set_allocator(&alloc_); //spec.sort_cmp_funs_.set_allocator(&alloc_); //spec.sort_collations_.set_allocator(&alloc_); spec.distinct_exprs_.destroy(); spec.cost_ = 1; spec.rows_ = 5000; spec.width_ = 20; if (OB_FAIL(spec.output_.init(3))) { LOG_WARN("failed to init output_", K(ret)); return ret; } int pos1 = is_vec ? 2000000 : 5000000; for (int i = 0; i < 3 ; ++i) { ObExpr *expr = static_cast (alloc_.alloc(sizeof(ObExpr))); if (OB_FAIL(spec.output_.push_back(expr))) { LOG_WARN("failed to push back expr", K(ret)); return ret; } expr->batch_result_ = (spec.batch_size_ > 0); expr->batch_idx_mask_ = (expr->batch_result_ ? UINT64_MAX : 0); expr->eval_batch_func_ = nullptr; expr->eval_func_ = nullptr; expr->frame_idx_ = 0; expr->datum_off_ = pos1; pos1 += sizeof(ObDatum) * op_eval_ctx_.max_batch_size_; expr->eval_info_off_ = pos1; pos1 += sizeof(ObEvalInfo); expr->eval_flags_off_ = pos1; pos1 += ObBitVector::memory_size(op_eval_ctx_.max_batch_size_); expr->pvt_skip_off_ = pos1; ObDatum *datums = expr->locate_batch_datums(op_eval_ctx_); for (int64_t j = 0; j < op_eval_ctx_.max_batch_size_; j++) { datums[j].ptr_ = op_eval_ctx_.frames_[0] + pos1; pos1 += (3 == i ? 522 : 8); } } if (OB_FAIL(spec.distinct_exprs_.init(3))) { LOG_WARN("failed to get output exprs", K(ret), K(spec.distinct_exprs_.capacity_)); return ret; } pos1 = is_vec ? 6000000 : 7000000; for (int i = 0; i < 3; ++i) { ObExpr *expr = static_cast(alloc_.alloc(sizeof(ObExpr)));//新建expr, 设置expr对应的datum, 在对应位置放置datum if (OB_FAIL(spec.distinct_exprs_.push_back(expr))) { return ret; } //expr->batch_result_ = (spec.batch_size_ > 0); //expr->batch_idx_mask_ = (expr->batch_result_ ? UINT64_MAX : 0); expr->eval_batch_func_ = nullptr; expr->eval_func_ = nullptr; expr->frame_idx_ = 0; expr->datum_off_ = pos1; pos1 += sizeof(ObDatum) * op_eval_ctx_.max_batch_size_; expr->eval_info_off_ = pos1; pos1 += sizeof(ObEvalInfo); expr->eval_flags_off_ = pos1; pos1 += ObBitVector::memory_size(op_eval_ctx_.max_batch_size_); expr->pvt_skip_off_ = pos1; ObDatum *datums = expr->locate_batch_datums(op_eval_ctx_); for (int64_t j = 0; j < op_eval_ctx_.max_batch_size_; j++) { datums[j].ptr_ = op_eval_ctx_.frames_[0] + pos1; pos1 += (3 == i ? 522 : 8); } } if (OB_FAIL(spec.cmp_funcs_.init(1))) { LOG_WARN("failed to compare function", K(ret)); } else { LOG_WARN("init funcs"); // 初始化compare func和hash func ObOrderDirection order_direction = default_asc_direction(); bool is_ascending = is_ascending_direction(order_direction); ObSortFieldCollation field_collation(0, CS_TYPE_BINARY, is_ascending, (is_null_first(order_direction) ^ is_ascending) ? NULL_LAST : NULL_FIRST); ObSortCmpFunc cmp_func; ObObjType tmp_type = ObIntType; cmp_func.cmp_func_ = ObDatumFuncs::get_nullsafe_cmp_func(tmp_type, tmp_type, field_collation.null_pos_, field_collation.cs_type_, SCALE_UNKNOWN_YET, lib::is_oracle_mode(), false); if (OB_FAIL(spec.cmp_funcs_.push_back(cmp_func))) { LOG_WARN("failed to push back sort function", K(ret)); } } return ret; } protected: ObArenaAllocator alloc_; ObMergeIntersectSpec spec1_; ObMergeIntersectSpec spec2_; ObMergeExceptSpec spec3_; ObMergeExceptSpec spec4_; SetDataGeneratorSpec spec5_; SetDataGeneratorSpec spec6_; ObMergeUnionSpec spec7_; ObMergeUnionSpec spec8_; SetDataGeneratorSpec spec9_; SetDataGeneratorSpec spec10_; ObMergeDistinctSpec spec11_; ObMergeDistinctSpec spec12_; ObMergeIntersectOp merge_intersect_vec_; ObMergeIntersectOp merge_intersect_; ObMergeExceptOp merge_except_vec_; ObMergeExceptOp merge_except_; ObMergeUnionOp merge_union_vec_; ObMergeUnionOp merge_union_; ObMergeDistinctOp merge_distinct_vec_; ObMergeDistinctOp merge_distinct_; ObOperator *merge_set_op_vec_; ObOperator *merge_set_op_; SetPlan merge_plan_vec_; SetPlan merge_plan_; }; int ObMergeSetVecTest::SetPlan::setup_plan(ObOperator *set_op) { int ret = OB_SUCCESS; bool is_vec = (left_.get_spec().batch_size_ > 0); bool is_distinct = (nullptr != dynamic_cast (set_op)); left_.init_expr(is_vec ? 0 : 8000000); right_.init_expr(is_vec ? 0 : 8000000); SetDataGeneratorSpec &left_spec = const_cast (left_.get_spec()); SetDataGeneratorSpec &right_spec = const_cast (right_.get_spec()); set_op_ = set_op; ObOpSpec &set_op_spec = const_cast (set_op_->get_spec()); left_spec.id_ = 0; right_spec.id_ = 1; set_op_spec.id_ = 2; //LOG_WARN("value:", K(left_spec), K(right_spec)); //set_op_->set_column_count(SetDataGenerator::CELL_CNT * 2); 没有的参数 left_spec.plan_=&plan_; right_spec.plan_=&plan_; set_op_spec.plan_=&plan_; set_op_->ctx_.set_my_session(&session_); set_op_->ctx_.init_phy_op(is_distinct ? 2 : 3); set_op_->ctx_.create_physical_plan_ctx(); ObOperator **children_ptr = static_cast(exec_ctx_.get_allocator().alloc(sizeof(ObOperator *) * (is_distinct ? 1 : 2))); ObOpSpec **spec_children_ptr = static_cast(exec_ctx_.get_allocator().alloc(sizeof(ObOpSpec *) * (is_distinct ? 1 : 2))); if (OB_ISNULL(children_ptr)) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("alloc for children_ptr failed ", K(ret)); } else if (OB_ISNULL(spec_children_ptr)) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("alloc for spec_children_ptr falied", K(ret)); } else { children_ptr[0] = static_cast(&left_); spec_children_ptr[0] = static_cast(&left_spec); if (!is_distinct) { children_ptr[1] = static_cast(&right_); spec_children_ptr[1] = static_cast(&right_spec); } } if (OB_FAIL(set_op_->set_children_pointer(children_ptr, (is_distinct ? 1 : 2)))) { LOG_WARN("failed to set children for set op", K(ret)); } else if (OB_FAIL(set_op_spec.set_children_pointer(spec_children_ptr, (is_distinct ? 1 : 2)))) { LOG_WARN("failed to set spec children for set op", K(ret)); } //set_op_->set_distinct(true); 没有的参数 // setup context ObString tenant_name("test"); if (OB_FAIL(ret)) { } else if (OB_FAIL(session_.test_init(0, 0, 0, NULL))) { } else if (OB_FAIL(ObPreProcessSysVars::init_sys_var())) { } else if (OB_FAIL(session_.load_default_sys_variable(false, true))) { } else if (OB_FAIL(session_.init_tenant(tenant_name, OB_SYS_TENANT_ID))) { } else if (FALSE_IT(exec_ctx_.set_my_session(&session_))) { } else if (OB_FAIL(exec_ctx_.init_phy_op((is_distinct ? 2 : 3)))) { } else if (OB_FAIL(exec_ctx_.create_physical_plan_ctx())) { } LOG_WARN("value:", K(left_spec), K(right_spec), K(set_op_spec)); return ret; } void ObMergeSetVecTest::setup_plan(SetPlan &plan, bool vec_algo, ObMergeSetVecTest::TestAlgo algo) { int ret = OB_SUCCESS; switch (algo) { case UNION: if (vec_algo) { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_union_vec_)); merge_set_op_vec_ = &merge_union_vec_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_vec_->get_spec())); if (OB_FAIL(generate_merge_set_spec(merge_spec, true))) { LOG_WARN("failed to generate merge_set_spec", K(ret)); } else { LOG_WARN("success to generate merge_set_spec", K(ret)); } } else { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_union_)); merge_set_op_ = &merge_union_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_->get_spec())); if (OB_FAIL(generate_merge_set_spec(merge_spec, false))) { LOG_WARN("failed to generate merge_set_spec", K(ret)); } else { LOG_WARN("success to generate merge_set_spec", K(ret)); } } break; case INTERSECT: if (vec_algo) { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_intersect_vec_)); merge_set_op_vec_ = &merge_intersect_vec_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_vec_->get_spec())); if (OB_FAIL(generate_merge_set_spec(merge_spec, true))) { LOG_WARN("failed to generate merge_set_spec", K(ret)); } else { LOG_WARN("success to generate merge_set_spec", K(ret)); } } else { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_intersect_)); merge_set_op_ = &merge_intersect_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_->get_spec())); if (OB_FAIL(generate_merge_set_spec(merge_spec, false))) { LOG_WARN("failed to generate merge_set_spec", K(ret)); } else { LOG_WARN("success to generate merge_set_spec", K(ret)); } } break; case EXCEPT: if (vec_algo) { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_except_vec_)); merge_set_op_vec_ = &merge_except_vec_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_vec_->get_spec())); generate_merge_set_spec(merge_spec, true); } else { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_except_)); merge_set_op_ = &merge_except_; ObMergeSetSpec &merge_spec = static_cast(const_cast (merge_set_op_->get_spec())); generate_merge_set_spec(merge_spec, false); } break; case DISTINCT: if (vec_algo) { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_distinct_vec_)); merge_set_op_vec_ = &merge_distinct_vec_; ObMergeDistinctSpec &merge_spec = static_cast(const_cast (merge_set_op_vec_->get_spec())); generate_merge_distinct_spec(merge_spec, true); } else { ASSERT_EQ(OB_SUCCESS, plan.setup_plan(&merge_distinct_)); merge_set_op_ = &merge_distinct_; ObMergeDistinctSpec &merge_spec = static_cast(const_cast (merge_set_op_->get_spec())); generate_merge_distinct_spec(merge_spec, false); } break; default: break; } } void ObMergeSetVecTest::setup_test(TestAlgo algo, int32_t string_size, int64_t left_row_count, bool left_reverse, IdxCntFunc left_func, int64_t right_row_count, bool right_reverse, IdxCntFunc right_func) { SetPlan *plans[] = { &merge_plan_vec_, &merge_plan_ }; for (int i = 0; i < 2; i++) { auto &plan = *plans[i]; setup_plan(plan, i == 0 ? true : false, algo); plan.left_.row_cnt_ = left_row_count; plan.right_.row_cnt_ = right_row_count; plan.left_.string_size_ = string_size; plan.right_.string_size_ = string_size; UNUSED(left_reverse); UNUSED(left_func); UNUSED(right_reverse); UNUSED(right_func); /*if (&plan != &merge_plan_) { plan.left_.reverse_ = left_reverse; plan.right_.reverse_ = right_reverse; }*/ //plan.left_.idx_cnt_func_ = left_func; //plan.right_.idx_cnt_func_ = right_func; ASSERT_EQ(OB_SUCCESS, plan.left_.test_init()); ASSERT_EQ(OB_SUCCESS, plan.right_.test_init()); } } void ObMergeSetVecTest::run_test(int64_t print_row_cnt) { UNUSED(print_row_cnt); ObArenaAllocator alloc; typedef ObArray ResArray; int64_t res_cell_cnt = 1; const ObBatchRows * child_brs = nullptr; auto fun_batch = [&](SetPlan &plan, ResArray &res)->void { spec5_.batch_size_ = BATCH_SIZE; spec6_.batch_size_ = BATCH_SIZE; ASSERT_EQ(OB_SUCCESS, plan.set_op_->open()); int ret = OB_SUCCESS; while (OB_SUCC(ret)) { ret = plan.set_op_->get_next_batch(BATCH_SIZE, child_brs); ASSERT_EQ(OB_SUCCESS, ret); if (child_brs->end_ && 0 == child_brs->size_) { ret = OB_ITER_END; } else { auto &c = plan.set_op_->get_spec().output_[0]; ObDatum *result = c->locate_batch_datums(op_eval_ctx_); for (int64_t j = 0; j < child_brs->size_; ++j) { if (child_brs->skip_->at(j)) { continue; } auto r = static_cast(alloc.alloc(sizeof(int64_t) * res_cell_cnt)); ASSERT_TRUE(NULL != r); for (int64_t i = 0; i < res_cell_cnt; i++) { ObDatum &dtm = result[j]; r[i] = dtm.get_int(); } ASSERT_EQ(OB_SUCCESS, res.push_back(r)); } } } }; auto fun = [&](SetPlan &plan, ResArray &res)->void { spec5_.batch_size_ = 0; spec6_.batch_size_ = 0; ASSERT_EQ(OB_SUCCESS, plan.set_op_->open()); int ret = OB_SUCCESS; const ObNewRow *row = NULL; int64_t cnt = 0; while (OB_SUCC(ret)) { if (OB_FAIL(plan.set_op_->get_next_row())) { ASSERT_EQ(OB_ITER_END, ret); } else { auto r = static_cast(alloc.alloc(sizeof(int64_t) * res_cell_cnt)); ASSERT_TRUE(NULL != r); for (int64_t i = 0; i < res_cell_cnt; i++) { auto &c = plan.set_op_->get_spec().output_[0]; ObDatum &dtm = c->locate_expr_datum(op_eval_ctx_); r[i] = dtm.get_int(); } ASSERT_EQ(OB_SUCCESS, res.push_back(r)); } cnt++; } }; auto pfunc = [&](int64_t *r) { ObSqlString s; for (int64_t i = 0; i < res_cell_cnt; i++) { s.append_fmt("%ld, ", r[i]); } LOG_INFO("RES:", K(s.ptr())); }; ResArray merge_res_vec; fun_batch(merge_plan_vec_, merge_res_vec); ASSERT_FALSE(HasFatalFailure()); ResArray merge_res; fun(merge_plan_, merge_res); LOG_WARN("bp4"); ASSERT_FALSE(HasFatalFailure()); ASSERT_EQ(merge_res_vec.count(), merge_res.count()); auto sort_cmp = [&](int64_t *l, int64_t *r) { for (int64_t i = 0; i < res_cell_cnt; i++) { if (l[i] != r[i]) { return l[i] < r[i]; } } return false; }; LOG_WARN("bp5", K(merge_res_vec.count())); std::sort(&merge_res_vec.at(0), &merge_res_vec.at(0) + merge_res_vec.count(), sort_cmp); LOG_WARN("bp6", K(merge_res.count())); std::sort(&merge_res.at(0), &merge_res.at(0) + merge_res.count(), sort_cmp); for (int64_t i = 0; i < merge_res_vec.count(); i++) { ASSERT_EQ(*merge_res.at(i), *merge_res_vec.at(i)); } merge_set_op_vec_->close(); merge_set_op_->close(); merge_plan_vec_.~SetPlan(); merge_plan_.~SetPlan(); ASSERT_EQ(OB_SUCCESS, blocksstable::ObTmpFileManager::get_instance().files_.map_.size()); } int ObMergeSetVecTest::init_tenant_mgr() { int ret = OB_SUCCESS; ObTenantManager &tm = ObTenantManager::get_instance(); ObAddr self; oceanbase::rpc::frame::ObReqTransport req_transport(NULL, NULL); oceanbase::obrpc::ObSrvRpcProxy rpc_proxy; oceanbase::obrpc::ObCommonRpcProxy rs_rpc_proxy; oceanbase::share::ObRsMgr rs_mgr; uint64_t cluster_version = CLUSTER_VERSION_3000; common::ObClusterVersion::get_instance().update_cluster_version(cluster_version); EXPECT_EQ(cluster_version, common::ObClusterVersion::get_instance().get_cluster_version()); int64_t tenant_id = OB_SYS_TENANT_ID; self.set_ip_addr("127.0.0.1", 8086); ret = ObTenantConfigMgr::get_instance().add_tenant_config(tenant_id); EXPECT_EQ(OB_SUCCESS, ret); ret = tm.init(self, rpc_proxy, rs_rpc_proxy, rs_mgr, &req_transport, &ObServerConfig::get_instance()); EXPECT_EQ(OB_SUCCESS, ret); ret = tm.add_tenant(tenant_id); EXPECT_EQ(OB_SUCCESS, ret); ret = tm.set_tenant_mem_limit(tenant_id, 4L * 1024L * 1024L * 1024L, 8L * 1024L * 1024L * 1024L); EXPECT_EQ(OB_SUCCESS, ret); ret = tm.add_tenant(OB_SERVER_TENANT_ID); EXPECT_EQ(OB_SUCCESS, ret); const int64_t ulmt = 256LL << 30; const int64_t llmt = 256LL << 30; ret = tm.set_tenant_mem_limit(OB_SYS_TENANT_ID, ulmt, llmt); EXPECT_EQ(OB_SUCCESS, ret); ret = tm.set_tenant_mem_limit(OB_SERVER_TENANT_ID, ulmt, llmt); EXPECT_EQ(OB_SUCCESS, ret); auto ctx_allocator = lib::ObMallocAllocator::get_instance()->get_tenant_ctx_allocator( OB_SERVER_TENANT_ID, common::ObCtxIds::DEFAULT_CTX_ID); EXPECT_EQ(OB_SUCCESS, ret); ret = ctx_allocator->set_limit(8L * 1024L * 1024L * 1024L); EXPECT_EQ(OB_SUCCESS, ret); oceanbase::lib::set_memory_limit(128LL << 32); return ret; } /*TEST_F(ObMergeSetVecTest, test_intersect_dump) { setup_test(ObMergeSetVecTest::TestAlgo::INTERSECT, 512, 200000*3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 1 : 0; }, 200000*3, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 1 : 0; }); ASSERT_FALSE(HasFatalFailure()); run_test(); ASSERT_FALSE(HasFatalFailure()); } TEST_F(ObMergeSetVecTest, test_except_dump) { setup_test(ObMergeSetVecTest::TestAlgo::EXCEPT, 512, 200000 * 3, false, [](int64_t id, int64_t) { return id % 3 == 0 ? 1 : 0; }, 200000 * 3, false, [](int64_t id, int64_t) { return id % 5 == 0 ? 1 : 0; }); ASSERT_FALSE(HasFatalFailure()); run_test(); ASSERT_FALSE(HasFatalFailure()); }*/ TEST_F(ObMergeSetVecTest, test_union_dump) { setup_test(ObMergeSetVecTest::TestAlgo::UNION, 512, 200000 * 3 , false, [](int64_t id, int64_t) { return id % 3 == 0 ? 1 : 0; }, 200000 * 3 , false, [](int64_t id, int64_t) { return id % 5 == 0 ? 1 : 0; }); ASSERT_FALSE(HasFatalFailure()); run_test(); ASSERT_FALSE(HasFatalFailure()); } /*TEST_F(ObMergeSetVecTest, test_distinct_dump) { setup_test(ObMergeSetVecTest::TestAlgo::DISTINCT, 512, 200000 * 3 , false, [](int64_t id, int64_t) { return id % 3 == 0 ? 1 : 0; }, 200000 * 3 , false, [](int64_t id, int64_t) { return id % 5 == 0 ? 1 : 0; }); ASSERT_FALSE(HasFatalFailure()); run_test(); ASSERT_FALSE(HasFatalFailure()); }*/ } // end sql } // end oceanbase int main(int argc, char **argv) { exec_ctx_.eval_ctx_ = &op_eval_ctx_; op_eval_ctx_.max_batch_size_ = 256; op_eval_ctx_.frames_ = static_cast(exec_ctx_.get_allocator().alloc(sizeof(void *) * 2)); op_eval_ctx_.frames_[0] = (char *)exec_ctx_.get_allocator().alloc(10000000); oceanbase::sql::init_sql_factories(); OB_LOGGER.set_log_level("INFO"); ::testing::InitGoogleTest(&argc,argv); int ret = RUN_ALL_TESTS(); OB_LOGGER.disable(); return ret; }