init push

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

View File

@ -0,0 +1,9 @@
function(aggr_unittest case)
ob_unittest(${ARGV})
target_sources(${case} PRIVATE ../table/ob_fake_table.h ../set/ob_set_test_util.h)
endfunction()
aggr_unittest(test_hash_distinct)
aggr_unittest(test_hash_groupby)
aggr_unittest(test_merge_groupby)
aggr_unittest(test_scalar_aggregate)
aggr_unittest(test_merge_distinct)

View File

@ -0,0 +1,424 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_UNITTEST_SQL_AGGREGATE_TEST_UTILS_H_
#define OCEANBASE_UNITTEST_SQL_AGGREGATE_TEST_UTILS_H_
#ifndef private
#define private public
#endif
#ifndef protected
#define protected public
#endif
#include <gtest/gtest.h>
#include "sql/engine/table/ob_fake_table.h"
#include "sql/engine/aggregate/ob_groupby.h"
#include "sql/engine/aggregate/ob_scalar_aggregate.h"
#include "sql/session/ob_sql_session_info.h"
#include "share/ob_worker.h"
#include "observer/omt/ob_tenant_config_mgr.h"
#include "observer/ob_server.h"
using namespace oceanbase::share;
using namespace oceanbase::omt;
class TestAggregateFactory {
public:
TestAggregateFactory()
{}
~TestAggregateFactory()
{}
static void init(ObExecContext& ctx, ObGroupBy& groupby_op, int64_t col_count, bool is_distinct,
bool is_number = true, ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN,
ObCollationType group_cs_type = CS_TYPE_UTF8MB4_BIN)
{
ObPhysicalPlanCtx* plan_ctx = NULL;
groupby_op.reset();
groupby_op.reuse();
fake_table_.reset();
fake_table_.reuse();
result_table_.reset();
result_table_.reuse();
physical_plan_.reset();
OBSERVER.init_schema();
OBSERVER.init_tz_info_mgr();
ASSERT_EQ(OB_SUCCESS, ObTenantConfigMgr::get_instance().add_tenant_config(1));
ASSERT_EQ(OB_SUCCESS, my_session_.init_tenant(ObString::make_string("sys"), 1));
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session_.load_default_sys_variable(false, true));
THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + 6000000000);
fake_table_.set_column_count(col_count);
result_table_.set_column_count(col_count + (is_number ? 5 : 3) + (is_distinct ? 1 : 0)); // sum, avg
groupby_op.set_column_count(col_count + (is_number ? 5 : 3) + (is_distinct ? 1 : 0));
fake_table_.set_id(0);
result_table_.set_id(1);
groupby_op.set_id(2);
fake_table_.set_phy_plan(&physical_plan_);
result_table_.set_phy_plan(&physical_plan_);
groupby_op.set_phy_plan(&physical_plan_);
groupby_op.init(10);
groupby_op.set_child(0, fake_table_);
ctx.set_my_session(&my_session_);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ASSERT_EQ(OB_SUCCESS, ctx.create_physical_plan_ctx());
plan_ctx = ctx.get_physical_plan_ctx();
ASSERT_FALSE(NULL == plan_ctx);
plan_ctx->set_phy_plan(&physical_plan_);
add_aggr_column(groupby_op, is_distinct, is_number, agg_cs_type);
groupby_op.add_group_column_idx(2, group_cs_type);
}
static void init(ObExecContext& ctx, ObScalarAggregate& scalar_aggr_op, int64_t col_count, bool is_distinct,
bool is_number = true, ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN)
{
ObPhysicalPlanCtx* plan_ctx = NULL;
scalar_aggr_op.reset();
scalar_aggr_op.reuse();
fake_table_.reset();
fake_table_.reuse();
result_table_.reset();
result_table_.reuse();
physical_plan_.reset();
OBSERVER.init_schema();
OBSERVER.init_tz_info_mgr();
ASSERT_EQ(OB_SUCCESS, ObTenantConfigMgr::get_instance().add_tenant_config(1));
ASSERT_EQ(OB_SUCCESS, my_session_.init_tenant(ObString::make_string("sys"), 1));
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session_.load_default_sys_variable(false, true));
fake_table_.set_column_count(col_count);
result_table_.set_column_count(col_count + (is_number ? 5 : 3) + (is_distinct ? 1 : 0)); // sum, avg
scalar_aggr_op.set_column_count(col_count + (is_number ? 5 : 3) + (is_distinct ? 1 : 0));
scalar_aggr_op.init(10);
fake_table_.set_id(0);
result_table_.set_id(1);
scalar_aggr_op.set_id(2);
fake_table_.set_phy_plan(&physical_plan_);
result_table_.set_phy_plan(&physical_plan_);
scalar_aggr_op.set_phy_plan(&physical_plan_);
scalar_aggr_op.set_child(0, fake_table_);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ctx.set_my_session(&my_session_);
ASSERT_EQ(OB_SUCCESS, ctx.create_physical_plan_ctx());
plan_ctx = ctx.get_physical_plan_ctx();
ASSERT_FALSE(NULL == plan_ctx);
plan_ctx->set_phy_plan(&physical_plan_);
add_aggr_column(scalar_aggr_op, is_distinct, is_number, agg_cs_type);
}
static void init(ObExecContext& ctx, ObScalarAggregate& scalar_aggr_op, int64_t col_count)
{
ObPhysicalPlanCtx* plan_ctx = NULL;
scalar_aggr_op.reset();
scalar_aggr_op.reuse();
fake_table_.reset();
fake_table_.reuse();
result_table_.reset();
result_table_.reuse();
physical_plan_.reset();
OBSERVER.init_schema();
OBSERVER.init_tz_info_mgr();
ASSERT_EQ(OB_SUCCESS, ObTenantConfigMgr::get_instance().add_tenant_config(1));
ASSERT_EQ(OB_SUCCESS, my_session_.init_tenant(ObString::make_string("sys"), 1));
ASSERT_EQ(OB_SUCCESS, ObPreProcessSysVars::init_sys_var());
ASSERT_EQ(OB_SUCCESS, my_session_.load_default_sys_variable(false, true));
scalar_aggr_op.init(10);
fake_table_.set_column_count(col_count);
result_table_.set_column_count(col_count + 3); // avg(c), avg(b), avg(a)
scalar_aggr_op.set_column_count(col_count + 3);
fake_table_.set_id(0);
result_table_.set_id(1);
scalar_aggr_op.set_id(2);
fake_table_.set_phy_plan(&physical_plan_);
result_table_.set_phy_plan(&physical_plan_);
scalar_aggr_op.set_phy_plan(&physical_plan_);
scalar_aggr_op.set_child(0, fake_table_);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ctx.set_my_session(&my_session_);
ASSERT_EQ(OB_SUCCESS, ctx.create_physical_plan_ctx());
plan_ctx = ctx.get_physical_plan_ctx();
ASSERT_FALSE(NULL == plan_ctx);
plan_ctx->set_phy_plan(&physical_plan_);
add_aggr_column(scalar_aggr_op);
}
static void open_operator(ObExecContext& ctx, ObGroupBy& groupby_op)
{
ObPhyOperator* op = static_cast<ObPhyOperator*>(&groupby_op);
ASSERT_EQ(OB_SUCCESS, op->open(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.open(ctx));
}
static void close_operator(ObExecContext& ctx, ObGroupBy& groupby_op)
{
ObPhyOperator* op = static_cast<ObPhyOperator*>(&groupby_op);
ASSERT_EQ(OB_SUCCESS, op->close(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.close(ctx));
}
static void open_operator(ObExecContext& ctx, ObScalarAggregate& groupby_op)
{
ObPhyOperator* op = static_cast<ObPhyOperator*>(&groupby_op);
ASSERT_EQ(OB_SUCCESS, op->open(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.open(ctx));
}
static void close_operator(ObExecContext& ctx, ObScalarAggregate& groupby_op)
{
ObPhyOperator* op = static_cast<ObPhyOperator*>(&groupby_op);
ASSERT_EQ(OB_SUCCESS, op->close(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.close(ctx));
}
static ObFakeTable& get_fake_table()
{
return fake_table_;
}
static ObFakeTable& get_result_table()
{
return result_table_;
}
static ObPhysicalPlan& get_physical_plan()
{
return physical_plan_;
}
private:
static void add_aggr_column(
ObGroupBy& groupby_op, bool is_distinct, bool is_number = true, ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN)
{
ObAggregateExpression* col_expr = NULL;
ObPostExprItem expr_item;
// count(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->reset();
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(3);
col_expr->set_aggr_func(T_FUN_COUNT, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
// max(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(4);
col_expr->set_aggr_func(T_FUN_MAX, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
// min(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(5);
col_expr->set_aggr_func(T_FUN_MIN, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
// functions used only for number
if (is_number) {
// sum(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(6);
col_expr->set_aggr_func(T_FUN_SUM, is_distinct);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
// avg(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(7);
col_expr->set_aggr_func(T_FUN_AVG, is_distinct);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
}
if (is_distinct) {
// approx_count_distinct(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->reset();
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(is_number ? 8 : 6);
col_expr->set_aggr_func(T_FUN_APPROX_COUNT_DISTINCT, false);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
groupby_op.add_aggr_column(col_expr);
}
}
static void add_aggr_column(ObScalarAggregate& scalar_aggr_op)
{
ObAggregateExpression* col_expr = NULL;
ObPostExprItem expr_item;
// avg(c)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(0);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(3);
col_expr->set_aggr_func(T_FUN_AVG, false);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// avg(b)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(4);
col_expr->set_aggr_func(T_FUN_AVG, false);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// avg(a)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(2);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(5);
col_expr->set_aggr_func(T_FUN_AVG, false);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
}
static void add_aggr_column(ObScalarAggregate& scalar_aggr_op, bool is_distinct, bool is_number = true,
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN)
{
ObAggregateExpression* col_expr = NULL;
ObPostExprItem expr_item;
// count(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->reset();
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(3);
col_expr->set_aggr_func(T_FUN_COUNT, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// max(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(4);
col_expr->set_aggr_func(T_FUN_MAX, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// min(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(5);
col_expr->set_aggr_func(T_FUN_MIN, is_distinct);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// functions used only for number
if (is_number) {
// sum(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(6);
col_expr->set_aggr_func(T_FUN_SUM, is_distinct);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
// avg(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(7);
col_expr->set_aggr_func(T_FUN_AVG, is_distinct);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
}
if (is_distinct) {
// approx_count_distinct(aggr_col)
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, col_expr));
col_expr->reset();
col_expr->set_item_count(1);
expr_item.set_column(1);
col_expr->add_expr_item(expr_item);
col_expr->set_result_index(is_number ? 8 : 6);
col_expr->set_aggr_func(T_FUN_APPROX_COUNT_DISTINCT, false);
col_expr->set_collation_type(agg_cs_type);
col_expr->init_aggr_cs_type_count(1);
col_expr->add_aggr_cs_type(agg_cs_type);
col_expr->set_real_param_col_count(1);
scalar_aggr_op.add_aggr_column(col_expr);
}
}
private:
static ObPhysicalPlan physical_plan_;
static ObFakeTable fake_table_;
static ObFakeTable result_table_;
static ObSQLSessionInfo my_session_;
};
ObPhysicalPlan TestAggregateFactory::physical_plan_;
ObFakeTable TestAggregateFactory::fake_table_(TestAggregateFactory::physical_plan_.get_allocator());
ObFakeTable TestAggregateFactory::result_table_(TestAggregateFactory::physical_plan_.get_allocator());
ObSQLSessionInfo TestAggregateFactory::my_session_;
#endif /* OCEANBASE_UNITTEST_SQL_AGGREGATE_TEST_UTILS_H_ */

View File

@ -0,0 +1,668 @@
/**
* 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/ob_sql_init.h"
#include "sql/engine/table/ob_fake_table.h"
#include "sql/engine/aggregate/ob_hash_distinct.h"
#include "sql/engine/basic/ob_chunk_row_store.h"
#include "storage/blocksstable/ob_data_file_prepare.h"
#include "sql/session/ob_sql_session_info.h"
#include "share/config/ob_server_config.h"
#include "share/ob_define.h"
#include "observer/omt/ob_tenant_config_mgr.h"
namespace oceanbase {
using namespace omt;
namespace sql {
using namespace common;
class TestEnv : public ::testing::Environment {
public:
virtual void SetUp() override
{
GCONF.enable_sql_operator_dump.set_value("True");
uint64_t cluster_version = CLUSTER_VERSION_3000;
common::ObClusterVersion::get_instance().update_cluster_version(cluster_version);
int ret = OB_SUCCESS;
lib::ObMallocAllocator* malloc_allocator = lib::ObMallocAllocator::get_instance();
ret = malloc_allocator->create_tenant_ctx_allocator(OB_SYS_TENANT_ID);
ASSERT_EQ(OB_SUCCESS, ret);
ret = malloc_allocator->create_tenant_ctx_allocator(OB_SYS_TENANT_ID, common::ObCtxIds::WORK_AREA);
ASSERT_EQ(OB_SUCCESS, ret);
int s = (int)time(NULL);
SQL_ENG_LOG(WARN, "initial setup random seed", K(s));
srandom(s);
}
virtual void TearDown() override
{}
};
#define CALL(func, ...) \
func(__VA_ARGS__); \
ASSERT_FALSE(HasFatalFailure());
class TestHashDistinct : public ObHashDistinct {
public:
TestHashDistinct() : ObHashDistinct(alloc_)
{}
~TestHashDistinct()
{}
};
#define CALL(func, ...) \
func(__VA_ARGS__); \
ASSERT_FALSE(HasFatalFailure());
class TestHashDistinctTest : public blocksstable::TestDataFilePrepare {
public:
TestHashDistinctTest() : blocksstable::TestDataFilePrepare("TestDisk_distinct", 2 << 20, 5000)
{}
virtual ~TestHashDistinctTest();
virtual void SetUp() override
{
int ret = OB_SUCCESS;
ASSERT_EQ(OB_SUCCESS, init_tenant_mgr());
blocksstable::TestDataFilePrepare::SetUp();
ret = blocksstable::ObTmpFileManager::get_instance().init();
ASSERT_EQ(OB_SUCCESS, ret);
ret = blocksstable::ObTmpFileManager::get_instance().start();
ASSERT_EQ(OB_SUCCESS, ret);
row_.count_ = COLS;
row_.cells_ = cells_;
cells_[1].set_null();
row_verify_.count_ = COLS;
row_verify_.cells_ = cells_;
row_verify_.projector_size_ = 0;
memset(str_buf_, 'z', BUF_SIZE);
memset(hit_val_base, '1', BUF_SIZE);
memset(hit_val, '0', BUF_SIZE);
SQL_ENG_LOG(WARN, "setup finished", K_(row));
}
int init_tenant_mgr();
virtual void TearDown() override
{
blocksstable::ObTmpFileManager::get_instance().destroy();
blocksstable::TestDataFilePrepare::TearDown();
common::ObModItem mod;
lib::get_tenant_mod_memory(tenant_id_, static_cast<int>(mod_id_), mod);
ASSERT_EQ(0, mod.hold_);
lib::get_tenant_mod_memory(tenant_id_, static_cast<int>(mod_id2_), mod);
ASSERT_EQ(0, mod.hold_);
lib::get_tenant_mod_memory(tenant_id_, static_cast<int>(mod_id3_), mod);
ASSERT_EQ(0, mod.hold_);
ObTenantManager::get_instance().destroy();
SQL_ENG_LOG(WARN, "TearDown finished");
}
ObNewRow& gen_row(int64_t row_id)
{
cells_[0].set_int(row_id);
int64_t max_size = 512;
if (enable_big_row_ && row_id > 0 && random() % 100000 < 5) {
max_size = 1 << 20;
}
int64_t size = 10 + random() % max_size;
cells_[2].set_varchar(str_buf_, (int)size);
return row_;
}
// varify next row
// template <typename T>
void verify_row(ObExecContext& ctx, TestHashDistinct& op, bool verify_all = false)
{
const ObNewRow* result_row = &row_verify_;
int ret = op.get_next_row(ctx, result_row);
ASSERT_EQ(OB_SUCCESS, ret);
int64_t v;
result_row->get_cell(0).get_int(v);
if (verify_all) {
result_row->get_cell(1).is_null();
ObString s = result_row->get_cell(2).get_varchar();
if (0 != strncmp(str_buf_, s.ptr(), s.length())) {
SQL_ENG_LOG(WARN, "verify failed", K(s.ptr()), K(s.length()));
}
ASSERT_EQ(0, strncmp(str_buf_, s.ptr(), s.length()));
}
ASSERT_EQ(hit_val[v], '0');
hit_val[v] = 1;
}
void verify_n_rows(ObExecContext& ctx, TestHashDistinct& op, int64_t n, bool verify_all = false, int64_t start = 0)
{
memset(hit_val, '0', BUF_SIZE);
for (int64_t i = start; i < n; i++) {
CALL(verify_row, ctx, op, verify_all);
}
ASSERT_EQ(0, memcpy(hit_val, hit_val_base, sizeof(char) * n));
}
void verify_all_rows(ObExecContext& ctx, TestHashDistinct& op, int64_t n, bool verify_all = false)
{
int64_t i = 0;
int64_t v;
memset(hit_val, '0', BUF_SIZE);
while (true) {
const ObNewRow* result_row = &row_verify_;
int ret = op.get_next_row(ctx, result_row);
if (OB_ITER_END == ret) {
break;
}
ASSERT_EQ(OB_SUCCESS, ret);
i++;
result_row->get_cell(0).get_int(v);
if (verify_all) {
result_row->get_cell(1).is_null();
ObString s = result_row->get_cell(2).get_varchar();
if (0 != strncmp(str_buf_, s.ptr(), s.length())) {
SQL_ENG_LOG(WARN, "verify failed", K(s.ptr()), K(s.length()), K(v), K(i));
}
ASSERT_EQ(0, strncmp(str_buf_, s.ptr(), s.length()));
}
if (hit_val[v] != '0') {
SQL_ENG_LOG(WARN, "alread hitted", K(i), K(v));
}
ASSERT_EQ(hit_val[v], '0');
hit_val[v] = '1';
}
if (n != i) {
SQL_ENG_LOG(WARN, "already hitted", K(i), K(v));
}
ASSERT_EQ(n, i);
ASSERT_EQ(0, MEMCMP(hit_val, hit_val_base, sizeof(char) * n));
}
void append_rows(int64_t cnt)
{
int64_t ret = OB_SUCCESS;
// int64_t base = fake_table_.get_rows();
for (int64_t i = 0; i < cnt; i++) {
ObNewRow& row = gen_row(i);
fake_table_.add_row(row);
ASSERT_EQ(OB_SUCCESS, ret);
// if (i % 1000 == 0) {
// LOG_WARN("appended rows:", K(i));
//}
}
// ASSERT_EQ(base + cnt, fake_table_.get_rows());
}
void init(ObExecContext& ctx, ObSQLSessionInfo& my_session, TestHashDistinct& hash_distinct, int64_t col_count)
{
ASSERT_EQ(OB_SUCCESS, my_session.test_init(0, 0, 0, NULL));
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("test", OB_SYS_TENANT_ID));
ctx.set_my_session(&my_session);
hash_distinct.reset();
hash_distinct.reuse();
fake_table_.reset();
fake_table_.reuse();
result_table_.reset();
result_table_.reuse();
physical_plan_.reset();
fake_table_.set_column_count(col_count);
result_table_.set_column_count(col_count);
result_table_.set_projector(projector, col_count);
fake_table_.set_projector(projector, col_count);
hash_distinct.set_projector(projector, col_count);
hash_distinct.set_column_count(col_count);
fake_table_.set_id(0);
result_table_.set_id(1);
hash_distinct.set_id(2);
fake_table_.set_phy_plan(&physical_plan_);
result_table_.set_phy_plan(&physical_plan_);
hash_distinct.set_phy_plan(&physical_plan_);
hash_distinct.set_child(0, fake_table_);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ASSERT_EQ(OB_SUCCESS, ctx.create_physical_plan_ctx());
ASSERT_FALSE(NULL == ctx.get_physical_plan_ctx());
ctx.get_physical_plan_ctx()->set_phy_plan(&physical_plan_);
}
void open_operator(ObExecContext& ctx, TestHashDistinct& hash_distinct)
{
ASSERT_EQ(OB_SUCCESS, hash_distinct.open(ctx));
ObHashDistinct::ObHashDistinctCtx* distinct_ctx = NULL;
bool is_null =
OB_ISNULL(distinct_ctx = GET_PHY_OPERATOR_CTX(ObHashDistinct::ObHashDistinctCtx, ctx, hash_distinct.get_id()));
ASSERT_EQ(is_null, false);
distinct_ctx->enable_sql_dumped_ = true;
ASSERT_EQ(OB_SUCCESS, result_table_.open(ctx));
}
void close_operator(ObExecContext& ctx, TestHashDistinct& hash_distinct)
{
ASSERT_EQ(OB_SUCCESS, hash_distinct.close(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.close(ctx));
}
ObFakeTable& get_fake_table()
{
return fake_table_;
}
ObFakeTable& get_result_table()
{
return result_table_;
}
ObPhysicalPlan& get_physical_plan()
{
return physical_plan_;
}
protected:
ObFakeTable fake_table_;
ObFakeTable result_table_;
ObPhysicalPlan physical_plan_;
int32_t projector[3] = {0, 1, 2};
const static int64_t COLS = 3;
bool enable_big_row_ = false;
ObObj cells_[COLS];
ObObj ver_cells_[COLS];
ObNewRow row_;
ObNewRow row_verify_;
const static int64_t BUF_SIZE = 2 << 20;
char str_buf_[BUF_SIZE];
char hit_val[BUF_SIZE];
char hit_val_base[BUF_SIZE];
private:
int64_t tenant_id_ = OB_SYS_TENANT_ID;
int64_t ctx_id_ = ObCtxIds::WORK_AREA;
int64_t mod_id_ = ObNewModIds::TEST1;
int64_t mod_id2_ = ObNewModIds::TEST2;
int64_t mod_id3_ = ObNewModIds::TEST3;
// disallow copy
TestHashDistinctTest(const TestHashDistinctTest& other);
TestHashDistinctTest& operator=(const TestHashDistinctTest& other);
private:
// data members
};
TestHashDistinctTest::~TestHashDistinctTest()
{}
int TestHashDistinctTest::init_tenant_mgr()
{
int ret = OB_SUCCESS;
ObTenantManager& tm = ObTenantManager::get_instance();
ObAddr self;
oceanbase::rpc::frame::ObReqTransport req_transport(NULL, NULL);
oceanbase::obrpc::ObSrvRpcProxy rpc_proxy;
oceanbase::obrpc::ObCommonRpcProxy rs_rpc_proxy;
oceanbase::share::ObRsMgr rs_mgr;
int64_t tenant_id = OB_SYS_TENANT_ID;
self.set_ip_addr("127.0.0.1", 8086);
ret = ObTenantConfigMgr::get_instance().add_tenant_config(tenant_id);
EXPECT_EQ(OB_SUCCESS, ret);
GCONF.enable_sql_operator_dump.set_value("True");
uint64_t cluster_version = CLUSTER_VERSION_3000;
common::ObClusterVersion::get_instance().update_cluster_version(cluster_version);
ret = tm.init(self, rpc_proxy, rs_rpc_proxy, rs_mgr, &req_transport, &ObServerConfig::get_instance());
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(tenant_id);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.set_tenant_mem_limit(tenant_id, 2L * 1024L * 1024L * 1024L, 4L * 1024L * 1024L * 1024L);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(OB_SYS_TENANT_ID);
EXPECT_EQ(OB_SUCCESS, ret);
ret = tm.add_tenant(OB_SERVER_TENANT_ID);
EXPECT_EQ(OB_SUCCESS, ret);
const int64_t ulmt = 128LL << 30;
const int64_t llmt = 128LL << 30;
ret = tm.set_tenant_mem_limit(OB_SYS_TENANT_ID, ulmt, llmt);
EXPECT_EQ(OB_SUCCESS, ret);
oceanbase::lib::set_memory_limit(128LL << 32);
return ret;
}
TEST_F(TestHashDistinctTest, test_big_data00)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
hash_distinct.init(1);
hash_distinct.add_distinct_column(0, cs_type);
// hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 1000000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_big_data01)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 1000000);
CALL(append_rows, 100000);
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
hash_distinct.init(1);
hash_distinct.add_distinct_column(0, cs_type);
// hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 1000000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_utf8mb4_bin)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_BIN;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
// fake table: distinct column(c1)
ADD_ROW(fake_table, COL("r"), COL(1), COL(1));
ADD_ROW(fake_table, COL("r"), COL(1), COL(2));
ADD_ROW(fake_table, COL("s"), COL(2), COL(3));
ADD_ROW(fake_table, COL("s"), COL(1), COL(3));
ADD_ROW(fake_table, COL("t"), COL(2), COL(1));
ADD_ROW(fake_table, COL("t"), COL(3), COL(2));
ADD_ROW(fake_table, COL("ß"), COL(3), COL(4));
ADD_ROW(result_table, COL("r"), COL(1), COL(1));
ADD_ROW(result_table, COL("s"), COL(2), COL(3));
ADD_ROW(result_table, COL("t"), COL(2), COL(1));
ADD_ROW(result_table, COL("ß"), COL(3), COL(4));
fake_table.set_rows(7);
fake_table.set_width(20);
ASSERT_EQ(OB_SUCCESS, hash_distinct.init(1));
ASSERT_EQ(OB_SUCCESS, hash_distinct.add_distinct_column(0, cs_type));
open_operator(ctx, hash_distinct);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_distinct, 0, 0, cs_type);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_utf8mb4_general_ci)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
// fake table: distinct column(c1)
ADD_ROW(fake_table, COL("r"), COL("r"), COL(1));
ADD_ROW(fake_table, COL("r"), COL("r"), COL(2));
ADD_ROW(fake_table, COL("s"), COL("s"), COL(3));
ADD_ROW(fake_table, COL("ß"), COL("s"), COL(4));
ADD_ROW(fake_table, COL("s"), COL("ß"), COL(3));
ADD_ROW(fake_table, COL("t"), COL("t"), COL(1));
ADD_ROW(fake_table, COL("t"), COL("t"), COL(2));
ADD_ROW(result_table, COL("r"), COL("r"), COL(1));
ADD_ROW(result_table, COL("s"), COL("s"), COL(3));
ADD_ROW(result_table, COL("t"), COL("t"), COL(1));
fake_table.set_rows(7);
fake_table.set_width(20);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_distinct, 0, 1, cs_type);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_all_in_mem)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
hash_distinct.set_mem_limit(64 * 1024 * 1024);
// fake table: distinct column(c1)
CALL(append_rows, 1000);
fake_table_.set_rows(1000);
fake_table_.set_width(530);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 1000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_all_in_mem1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
hash_distinct.set_mem_limit(64 * 1024 * 1024);
// fake table: distinct column(c1)
CALL(append_rows, 3000);
fake_table_.set_rows(3000);
fake_table_.set_width(530);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 3000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_all_in_mem2)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 3000);
CALL(append_rows, 3000);
CALL(append_rows, 3000);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
// ASSERT_EQ(3000, hash_distinct.get_rows());
CALL(verify_all_rows, ctx, hash_distinct, 3000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_big_data)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 20000);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 20000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_big_data2)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 20000);
CALL(append_rows, 20000);
CALL(append_rows, 20000);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 20000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_big_data3)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 50000);
CALL(append_rows, 50000);
CALL(append_rows, 50000);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 50000, true);
close_operator(ctx, hash_distinct);
}
TEST_F(TestHashDistinctTest, test_big_data4)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestHashDistinct hash_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
init(ctx, my_session, hash_distinct, 3);
enable_big_row_ = true;
hash_distinct.set_mem_limit(64 * 1024 * 1024 * 10);
// fake table: distinct column(c1)
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
CALL(append_rows, 1000000);
hash_distinct.init(2);
hash_distinct.add_distinct_column(0, cs_type);
hash_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, hash_distinct);
CALL(verify_all_rows, ctx, hash_distinct, 1000000, true);
close_operator(ctx, hash_distinct);
}
} // end namespace sql
} // end namespace oceanbase
int main(int argc, char** argv)
{
oceanbase::sql::init_sql_factories();
oceanbase::common::ObLogger::get_logger().set_log_level("WARN");
testing::InitGoogleTest(&argc, argv);
auto* env = new (oceanbase::sql::TestEnv);
testing::AddGlobalTestEnvironment(env);
int ret = RUN_ALL_TESTS();
OB_LOGGER.disable();
return ret;
}

View File

@ -0,0 +1,369 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include "sql/ob_sql_init.h"
#include "sql/engine/aggregate/ob_hash_groupby.h"
#include "sql/engine/aggregate/ob_aggregate_test_utils.h"
#include "lib/stat/ob_session_stat.h"
#include "storage/memtable/ob_row_compactor.h"
#include "sql/engine/test_engine_util.h"
#include "storage/blocksstable/ob_data_file_prepare.h"
using namespace oceanbase::common;
using namespace oceanbase::sql;
using namespace oceanbase::blocksstable;
class ObHashGroupbyTest : public TestDataFilePrepare {
public:
ObHashGroupbyTest();
virtual ~ObHashGroupbyTest();
virtual void SetUp();
virtual void TearDown();
private:
// disallow copy
ObHashGroupbyTest(const ObHashGroupbyTest& other);
ObHashGroupbyTest& operator=(const ObHashGroupbyTest& other);
private:
// data members
};
ObHashGroupbyTest::ObHashGroupbyTest() : TestDataFilePrepare("TestDisk_groupby", 2 << 20, 5000)
{}
ObHashGroupbyTest::~ObHashGroupbyTest()
{}
void ObHashGroupbyTest::SetUp()
{
TestDataFilePrepare::SetUp();
int ret = ObTmpFileManager::get_instance().init();
ASSERT_EQ(OB_SUCCESS, ret);
}
void ObHashGroupbyTest::TearDown()
{
ObTmpFileManager::get_instance().destroy();
TestDataFilePrepare::TearDown();
}
class TestHashGroupBy : public ObHashGroupBy {
public:
TestHashGroupBy() : ObHashGroupBy(alloc_)
{}
virtual ~TestHashGroupBy()
{}
};
TEST_F(ObHashGroupbyTest, test_utf8mb4_bin_agg)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
int64_t col_count = 3;
bool is_distinct = false;
bool is_number = false;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, hash_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_groupby, col_count, hash_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_utf8mb4_genaral_ci_agg)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
int64_t col_count = 3;
bool is_distinct = false;
bool is_number = false;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, hash_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("t"), COL("r"));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_groupby, col_count, hash_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_utf8mb4_general_ci_group)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
int64_t col_count = 3;
bool is_distinct = false;
bool is_number = true;
ObCollationType agg_cs_type = CS_TYPE_INVALID;
ObCollationType group_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, hash_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(2), COL("ß"));
ADD_ROW(fake_table, COL(2), COL(4), COL("s"));
ADD_ROW(fake_table, COL(3), COL(6), COL("ß"));
ADD_ROW(fake_table, COL(4), COL(8), COL("s"));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL(8), COL(2), COL(20.0), COL(5.0));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_groupby, col_count, hash_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_utf8mb4_bin_agg_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
int64_t col_count = 3;
bool is_distinct = true;
bool is_number = false;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, hash_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"), COL(4));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_groupby, col_count, hash_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_utf8mb4_general_ci_agg_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
int64_t col_count = 3;
bool is_distinct = true;
bool is_number = false;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, hash_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(3), COL("t"), COL("r"), COL(3));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, hash_groupby, col_count, hash_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_groupby_without_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN;
TestAggregateFactory::init(ctx, hash_groupby, 3, false);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(2), COL(2));
ADD_ROW(fake_table, COL(5), COL(2), COL(3));
ADD_ROW(fake_table, COL(4), COL(3), COL(4));
ADD_ROW(fake_table, COL(3), COL(1), COL(3));
ADD_ROW(fake_table, COL(6), COL(2), COL(1));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(4), COL(4));
ADD_ROW(result_table, COL(4), COL(3), COL(4), COL(2), COL(4), COL(3), COL(7.0), COL(3.5));
ADD_ROW(result_table, COL(2), COL(2), COL(2), COL(2), COL(3), COL(2), COL(5.0), COL(2.5));
ADD_ROW(result_table, COL(5), COL(2), COL(3), COL(2), COL(2), COL(1), COL(3.0), COL(1.5));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(2), COL(2), COL(1), COL(3.0), COL(1.5));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT(ctx, result_table, hash_groupby, agg_cs_type);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_groupby_varchar)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
TestAggregateFactory::init(ctx, hash_groupby, 3, false);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("1"), COL(1));
ADD_ROW(fake_table, COL(2), COL("2"), COL(2));
ADD_ROW(fake_table, COL(5), COL("2"), COL(3));
ADD_ROW(fake_table, COL(4), COL("3"), COL(4));
ADD_ROW(fake_table, COL(3), COL("1"), COL(3));
ADD_ROW(fake_table, COL(6), COL("2"), COL(1));
ADD_ROW(fake_table, COL(7), COL("3"), COL(2));
ADD_ROW(fake_table, COL(8), COL("4"), COL(4));
ADD_ROW(result_table, COL(4), COL("3"), COL(4), COL(2), COL("4"), COL("3"), COL_T(double, 7.0), COL_T(double, 3.5));
ADD_ROW(result_table, COL(2), COL("2"), COL(2), COL(2), COL("3"), COL("2"), COL_T(double, 5.0), COL_T(double, 2.5));
ADD_ROW(result_table, COL(5), COL("2"), COL(3), COL(2), COL("2"), COL("1"), COL_T(double, 3.0), COL_T(double, 1.5));
ADD_ROW(result_table, COL(1), COL("1"), COL(1), COL(2), COL("2"), COL("1"), COL_T(double, 3.0), COL_T(double, 1.5));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT(ctx, result_table, hash_groupby, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_groupby_with_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestHashGroupBy hash_groupby;
TestAggregateFactory::init(ctx, hash_groupby, 3, true);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(1), COL(1));
ADD_ROW(fake_table, COL(3), COL(2), COL(1));
ADD_ROW(fake_table, COL(4), COL(2), COL(1));
ADD_ROW(fake_table, COL(5), COL(1), COL(2));
ADD_ROW(fake_table, COL(6), COL(1), COL(2));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(5), COL(2));
ADD_ROW(result_table, COL(5), COL(1), COL(2), COL(3), COL(5), COL(1), COL(3), COL(9.0), COL(3.0));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(2), COL(2), COL(1), COL(2), COL(3.0), COL(1.5));
TestAggregateFactory::open_operator(ctx, hash_groupby);
EXCEPT_RESULT(ctx, result_table, hash_groupby, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, hash_groupby);
}
TEST_F(ObHashGroupbyTest, test_invalid_argument)
{
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObExecContext ctx1;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx1));
ObArenaAllocator alloc;
ObFakeTable fake_table(alloc);
TestHashGroupBy hash_groupby;
const ObNewRow* row = NULL;
ASSERT_EQ(OB_NOT_INIT, hash_groupby.open(ctx));
hash_groupby.reset();
ASSERT_EQ(OB_ERR_UNEXPECTED, hash_groupby.get_next_row(ctx, row));
hash_groupby.reset();
hash_groupby.set_id(0);
hash_groupby.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ASSERT_EQ(OB_NOT_INIT, hash_groupby.open(ctx));
hash_groupby.reset();
hash_groupby.set_id(0);
hash_groupby.set_column_count(3);
fake_table.set_id(1);
fake_table.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, hash_groupby.set_child(0, fake_table));
ASSERT_EQ(OB_SUCCESS, ctx1.init_phy_op(3));
ASSERT_EQ(OB_ERR_UNEXPECTED, hash_groupby.open(ctx1));
}
TEST_F(ObHashGroupbyTest, test_invalid_argument1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
TestHashGroupBy hash_groupby;
ObArenaAllocator alloc;
ObAggregateExpression col_expr(alloc);
TestAggregateFactory::init(ctx, hash_groupby, 3, false);
// prepare rows, equal in the first row
ADD_ROW(fake_table, COL(1), COL(2), COL(1));
ADD_ROW(fake_table, COL(2), COL(2), COL(1));
}
TEST_F(ObHashGroupbyTest, test_serialize_and_deserialize)
{
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObPhysicalPlan physical_plan;
TestHashGroupBy hash_groupby;
TestHashGroupBy deserialize_op;
char bin_buf[1024] = {'\0'};
int64_t buf_len = 1024;
int64_t data_len = 0;
int64_t pos = 0;
TestAggregateFactory::init(ctx, hash_groupby, 3, false);
ASSERT_EQ(OB_SUCCESS, hash_groupby.serialize(bin_buf, buf_len, pos));
ASSERT_EQ(pos, hash_groupby.get_serialize_size());
deserialize_op.set_phy_plan(&physical_plan);
data_len = pos;
pos = 0;
ASSERT_EQ(OB_SUCCESS, deserialize_op.deserialize(bin_buf, data_len, pos));
ASSERT_EQ(0, strcmp(to_cstring(hash_groupby), to_cstring(deserialize_op)));
}
void __attribute__((constructor(101))) init_SessionDIBuffer()
{
oceanbase::common::ObDITls<ObSessionDIBuffer>::get_instance();
}
int main(int argc, char** argv)
{
init_global_memory_pool();
init_sql_factories();
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,365 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include "sql/ob_sql_init.h"
#include "sql/engine/table/ob_fake_table.h"
#include "sql/engine/aggregate/ob_merge_distinct.h"
#include "sql/session/ob_sql_session_info.h"
#include "observer/omt/ob_tenant_config_mgr.h"
using namespace oceanbase::common;
using namespace oceanbase::sql;
using namespace oceanbase::omt;
class TestMergeDistinct : public ObMergeDistinct {
public:
TestMergeDistinct() : ObMergeDistinct(alloc_)
{}
~TestMergeDistinct()
{}
};
class TestMergeDistinctTest : public ::testing::Test {
public:
TestMergeDistinctTest();
virtual ~TestMergeDistinctTest();
virtual void SetUp();
virtual void TearDown();
void init(ObExecContext& ctx, TestMergeDistinct& merge_distinct, int64_t col_count)
{
ASSERT_EQ(OB_SUCCESS,
ObTenantConfigMgr::get_instance().add_tenant_config(ctx.get_my_session()->get_effective_tenant_id()));
merge_distinct.reset();
merge_distinct.reuse();
fake_table_.reset();
fake_table_.reuse();
result_table_.reset();
result_table_.reuse();
physical_plan_.reset();
fake_table_.set_column_count(col_count);
result_table_.set_column_count(col_count);
int32_t projector[3] = {0, 1, 2};
result_table_.set_projector(projector, col_count);
fake_table_.set_projector(projector, col_count);
merge_distinct.set_projector(projector, col_count);
merge_distinct.set_column_count(col_count);
fake_table_.set_id(0);
result_table_.set_id(1);
merge_distinct.set_id(2);
fake_table_.set_phy_plan(&physical_plan_);
result_table_.set_phy_plan(&physical_plan_);
merge_distinct.set_phy_plan(&physical_plan_);
merge_distinct.set_child(0, fake_table_);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ASSERT_EQ(OB_SUCCESS, ctx.create_physical_plan_ctx());
ASSERT_FALSE(NULL == ctx.get_physical_plan_ctx());
ctx.get_physical_plan_ctx()->set_phy_plan(&physical_plan_);
}
void open_operator(ObExecContext& ctx, TestMergeDistinct& merge_distinct)
{
ASSERT_EQ(OB_SUCCESS, merge_distinct.open(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.open(ctx));
}
void close_operator(ObExecContext& ctx, TestMergeDistinct& merge_distinct)
{
ASSERT_EQ(OB_SUCCESS, merge_distinct.close(ctx));
ASSERT_EQ(OB_SUCCESS, result_table_.close(ctx));
}
ObFakeTable& get_fake_table()
{
return fake_table_;
}
ObFakeTable& get_result_table()
{
return result_table_;
}
ObPhysicalPlan& get_physical_plan()
{
return physical_plan_;
}
protected:
ObFakeTable fake_table_;
ObFakeTable result_table_;
ObPhysicalPlan physical_plan_;
private:
// disallow copy
TestMergeDistinctTest(const TestMergeDistinctTest& other);
TestMergeDistinctTest& operator=(const TestMergeDistinctTest& other);
private:
// data members
};
TestMergeDistinctTest::TestMergeDistinctTest()
{}
TestMergeDistinctTest::~TestMergeDistinctTest()
{}
void TestMergeDistinctTest::SetUp()
{}
void TestMergeDistinctTest::TearDown()
{}
TEST_F(TestMergeDistinctTest, test_utf8mb4_bin)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestMergeDistinct merge_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_BIN;
ObSQLSessionInfo my_session;
ASSERT_EQ(OB_SUCCESS, my_session.test_init(0, 0, 0, NULL));
ctx.set_my_session(&my_session);
init(ctx, merge_distinct, 3);
// fake table: distinct column(c1)
ADD_ROW(fake_table, COL("r"), COL(1), COL(1));
ADD_ROW(fake_table, COL("r"), COL(1), COL(2));
ADD_ROW(fake_table, COL("s"), COL(2), COL(3));
ADD_ROW(fake_table, COL("s"), COL(1), COL(3));
ADD_ROW(fake_table, COL("t"), COL(2), COL(1));
ADD_ROW(fake_table, COL("t"), COL(3), COL(2));
ADD_ROW(fake_table, COL("ß"), COL(3), COL(4));
ADD_ROW(result_table, COL("r"), COL(0), COL(0));
ADD_ROW(result_table, COL("s"), COL(1), COL(1));
ADD_ROW(result_table, COL("t"), COL(2), COL(2));
ADD_ROW(result_table, COL("ß"), COL(3), COL(3));
merge_distinct.add_distinct_column(0, cs_type);
open_operator(ctx, merge_distinct);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_distinct, 0, 0, cs_type);
close_operator(ctx, merge_distinct);
}
TEST_F(TestMergeDistinctTest, test_utf8mb4_general_ci)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = get_fake_table();
ObFakeTable& result_table = get_result_table();
TestMergeDistinct merge_distinct;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObSQLSessionInfo my_session;
ASSERT_EQ(OB_SUCCESS, my_session.test_init(0, 0, 0, NULL));
ctx.set_my_session(&my_session);
init(ctx, merge_distinct, 3);
// fake table: distinct column(c1)
ADD_ROW(fake_table, COL("r"), COL("r"), COL(1));
ADD_ROW(fake_table, COL("r"), COL("r"), COL(2));
ADD_ROW(fake_table, COL("s"), COL("s"), COL(3));
ADD_ROW(fake_table, COL("ß"), COL("s"), COL(4));
ADD_ROW(fake_table, COL("s"), COL("ß"), COL(3));
ADD_ROW(fake_table, COL("t"), COL("t"), COL(1));
ADD_ROW(fake_table, COL("t"), COL("t"), COL(2));
ADD_ROW(result_table, COL("r"), COL("r"), COL(0));
ADD_ROW(result_table, COL("ß"), COL("ß"), COL(0));
ADD_ROW(result_table, COL("t"), COL("t"), COL(0));
merge_distinct.add_distinct_column(0, cs_type);
merge_distinct.add_distinct_column(1, cs_type);
open_operator(ctx, merge_distinct);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_distinct, 0, 1, cs_type);
close_operator(ctx, merge_distinct);
}
/*
TEST_F(TestMergeDistinctTest, test_merge_distinct_1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &fake_table = get_fake_table();
ObFakeTable &result_table = get_result_table();
TestMergeDistinct merge_distinct;
init(ctx, merge_distinct, 3);
//fake table: distinct column(c1)
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(1), COL(1), COL(2));
ADD_ROW(fake_table, COL(5), COL(2), COL(3));
ADD_ROW(fake_table, COL(5), COL(3), COL(4));
ADD_ROW(fake_table, COL(6), COL(1), COL(3));
ADD_ROW(fake_table, COL(6), COL(2), COL(1));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(4), COL(4));
ADD_ROW(result_table, COL(1), COL(1), COL(1));
ADD_ROW(result_table, COL(5), COL(2), COL(3));
ADD_ROW(result_table, COL(6), COL(1), COL(3));
ADD_ROW(result_table, COL(7), COL(3), COL(2));
ADD_ROW(result_table, COL(8), COL(4), COL(4));
merge_distinct.add_distinct_column(0);
open_operator(ctx, merge_distinct);
EXCEPT_RESULT(ctx, result_table, merge_distinct);
close_operator(ctx, merge_distinct);
}
TEST_F(TestMergeDistinctTest, test_merge_distinct_2)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &fake_table = get_fake_table();
ObFakeTable &result_table = get_result_table();
TestMergeDistinct merge_distinct;
init(ctx, merge_distinct, 3);
//fake table: distinct column(c1, c2)
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(1), COL(1), COL(2));
ADD_ROW(fake_table, COL(5), COL(2), COL(3));
ADD_ROW(fake_table, COL(5), COL(3), COL(4));
ADD_ROW(fake_table, COL(6), COL(1), COL(3));
ADD_ROW(fake_table, COL(6), COL(1), COL(1));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(7), COL(3), COL(4));
ADD_ROW(result_table, COL(1), COL(1), COL(1));
ADD_ROW(result_table, COL(5), COL(2), COL(3));
ADD_ROW(result_table, COL(5), COL(3), COL(4));
ADD_ROW(result_table, COL(6), COL(1), COL(3));
ADD_ROW(result_table, COL(7), COL(3), COL(2));
merge_distinct.add_distinct_column(0);
merge_distinct.add_distinct_column(1);
open_operator(ctx, merge_distinct);
EXCEPT_RESULT(ctx, result_table, merge_distinct);
close_operator(ctx, merge_distinct);
}
TEST_F(TestMergeDistinctTest, test_merge_distinct_with_calc)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &fake_table = get_fake_table();
ObFakeTable &result_table = get_result_table();
TestMergeDistinct merge_distinct;
init(ctx, merge_distinct, 4);
merge_distinct.add_distinct_column(0);
merge_distinct.add_distinct_column(1);
// calculate c3 + 1
ObColumnExpression *calc_expr = NULL;
ASSERT_EQ(OB_SUCCESS, ObSqlExpressionUtil::make_sql_expr(&physical_plan_, calc_expr));
ASSERT_FALSE(NULL == calc_expr);
calc_expr->set_result_index(3);
ObPostExprItem calc_item;
calc_item.set_int(1);
calc_item.set_item_type(T_INT);
ASSERT_EQ(OB_SUCCESS, calc_expr->add_expr_item(calc_item));
//column c3
calc_item.set_column(2);
ASSERT_EQ(OB_SUCCESS, calc_expr->add_expr_item(calc_item));
calc_item.set_op("+", 2);
ASSERT_EQ(OB_SUCCESS, calc_expr->add_expr_item(calc_item));
ASSERT_EQ(OB_SUCCESS, merge_distinct.add_compute(calc_expr));
//fake table: distinct column(c1, c2)
ADD_ROW(fake_table, COL(1), COL(1), COL(1), COL(null));
ADD_ROW(fake_table, COL(1), COL(1), COL(2), COL(null));
ADD_ROW(fake_table, COL(5), COL(2), COL(3), COL(null));
ADD_ROW(fake_table, COL(5), COL(3), COL(4), COL(null));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(2));
ADD_ROW(result_table, COL(5), COL(2), COL(3), COL(4));
ADD_ROW(result_table, COL(5), COL(3), COL(4), COL(5));
open_operator(ctx, merge_distinct);
EXCEPT_RESULT(ctx, result_table, merge_distinct);
close_operator(ctx, merge_distinct);
}
TEST_F(TestMergeDistinctTest, test_aggr_empty_set)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
TestMergeDistinct merge_distinct;
init(ctx, merge_distinct, 3);
open_operator(ctx, merge_distinct);
EXCEPT_RESULT(ctx, get_result_table(), merge_distinct);
close_operator(ctx, merge_distinct);
}
TEST_F(TestMergeDistinctTest, test_serialize_and_deserialize)
{
ObExecContext ctx;
ObPhysicalPlan physical_plan;
TestMergeDistinct merge_distinct;
TestMergeDistinct deserialize_op;
char bin_buf[1024] = {'\0'};
int64_t buf_len = 1024;
int64_t data_len = 0;
int64_t pos = 0;
init(ctx, merge_distinct, 3);
merge_distinct.add_distinct_column(0);
merge_distinct.add_distinct_column(1);
ASSERT_EQ(OB_SUCCESS, merge_distinct.serialize(bin_buf, buf_len, pos));
ASSERT_EQ(pos, merge_distinct.get_serialize_size());
deserialize_op.set_phy_plan(&physical_plan);
data_len = pos;
pos = 0;
ASSERT_EQ(OB_SUCCESS, deserialize_op.deserialize(bin_buf, data_len, pos));
ASSERT_EQ(0, strcmp(to_cstring(merge_distinct), to_cstring(deserialize_op)));
}
TEST_F(TestMergeDistinctTest, test_invalid_argument)
{
ObExecContext ctx;
ObExecContext ctx1;
ObFakeTable fake_table;
TestMergeDistinct merge_distinct;
const ObNewRow *row = NULL;
ASSERT_EQ(OB_NOT_INIT, merge_distinct.open(ctx));
merge_distinct.reset();
ASSERT_EQ(OB_ERR_UNEXPECTED, merge_distinct.get_next_row(ctx, row));
merge_distinct.reset();
merge_distinct.set_id(0);
merge_distinct.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, ctx.init(3));
ASSERT_EQ(OB_NOT_INIT, merge_distinct.open(ctx));
merge_distinct.reset();
merge_distinct.set_id(4);
merge_distinct.set_column_count(3);
fake_table.set_id(1);
fake_table.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, merge_distinct.set_child(0, fake_table));
ASSERT_EQ(OB_SUCCESS, ctx1.init(3));
ASSERT_EQ(OB_INVALID_ARGUMENT, merge_distinct.open(ctx1));
}
*/
int main(int argc, char** argv)
{
init_global_memory_pool();
init_sql_factories();
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,403 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include "sql/ob_sql_init.h"
#include "sql/engine/aggregate/ob_merge_groupby.h"
#include "sql/engine/aggregate/ob_aggregate_test_utils.h"
#include "storage/blocksstable/ob_data_file_prepare.h"
using namespace oceanbase::common;
using namespace oceanbase::sql;
using namespace oceanbase::blocksstable;
class ObMergeGroupbyTest : public TestDataFilePrepare {
public:
ObMergeGroupbyTest();
virtual ~ObMergeGroupbyTest();
virtual void SetUp();
virtual void TearDown();
private:
// disallow copy
ObMergeGroupbyTest(const ObMergeGroupbyTest& other);
ObMergeGroupbyTest& operator=(const ObMergeGroupbyTest& other);
private:
// data members
};
ObMergeGroupbyTest::ObMergeGroupbyTest() : TestDataFilePrepare("TestDisk_mergegroupby", 2 << 20, 5000)
{}
ObMergeGroupbyTest::~ObMergeGroupbyTest()
{}
void ObMergeGroupbyTest::SetUp()
{
TestDataFilePrepare::SetUp();
int ret = ObTmpFileManager::get_instance().init();
ASSERT_EQ(OB_SUCCESS, ret);
}
void ObMergeGroupbyTest::TearDown()
{
ObTmpFileManager::get_instance().destroy();
TestDataFilePrepare::TearDown();
}
class TestMergeGroupBy : public ObMergeGroupBy {
public:
TestMergeGroupBy() : ObMergeGroupBy(alloc_)
{}
~TestMergeGroupBy()
{}
};
TEST_F(ObMergeGroupbyTest, test_utf8mb4_bin_agg)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
bool is_distinct = false;
bool is_number = false;
int64_t col_count = 3;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, merge_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(fake_table, COL(5), COL("s"), COL(2));
ADD_ROW(fake_table, COL(6), COL("r"), COL(2));
ADD_ROW(fake_table, COL(7), COL("ß"), COL(2));
ADD_ROW(fake_table, COL(8), COL("t"), COL(2));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, col_count, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_utf8mb4_genaral_ci_agg)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
bool is_distinct = false;
bool is_number = false;
int64_t col_count = 3;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, merge_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(fake_table, COL(5), COL("s"), COL(2));
ADD_ROW(fake_table, COL(6), COL("r"), COL(2));
ADD_ROW(fake_table, COL(7), COL("ß"), COL(2));
ADD_ROW(fake_table, COL(8), COL("t"), COL(2));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("t"), COL("r"));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("t"), COL("r"));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, col_count, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_utf8mb4_genaral_ci_group)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
bool is_distinct = false;
bool is_number = true;
int64_t col_count = 3;
ObCollationType agg_cs_type = CS_TYPE_INVALID;
ObCollationType group_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, merge_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(2), COL("ß"));
ADD_ROW(fake_table, COL(2), COL(4), COL("s"));
ADD_ROW(fake_table, COL(3), COL(6), COL("ß"));
ADD_ROW(fake_table, COL(4), COL(8), COL("s"));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL(8), COL(2), COL(20.0), COL(5.0));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, col_count, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_gutf8mb4_bin_agg_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
bool is_distinct = true;
bool is_number = false;
int64_t col_count = 3;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_BIN;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, merge_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(fake_table, COL(5), COL("r"), COL(2));
ADD_ROW(fake_table, COL(6), COL("s"), COL(2));
ADD_ROW(fake_table, COL(7), COL("t"), COL(2));
ADD_ROW(fake_table, COL(8), COL("ß"), COL(2));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"), COL(4));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"), COL(4));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, col_count, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_utf8mb4_genaral_ci_agg_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
bool is_distinct = true;
bool is_number = false;
int64_t col_count = 3;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
ObCollationType group_cs_type = CS_TYPE_INVALID;
TestAggregateFactory::init(ctx, merge_groupby, col_count, is_distinct, is_number, agg_cs_type, group_cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(1));
ADD_ROW(fake_table, COL(3), COL("t"), COL(1));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(1));
ADD_ROW(fake_table, COL(1), COL("r"), COL(2));
ADD_ROW(fake_table, COL(2), COL("s"), COL(2));
ADD_ROW(fake_table, COL(3), COL("t"), COL(2));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(2));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(3), COL("t"), COL("r"), COL(3));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(3), COL("t"), COL("r"), COL(3));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, col_count, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_groupby_without_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(2), COL(1));
ADD_ROW(fake_table, COL(3), COL(2), COL(1));
ADD_ROW(fake_table, COL(4), COL(3), COL(1));
ADD_ROW(fake_table, COL(5), COL(1), COL(2));
ADD_ROW(fake_table, COL(6), COL(2), COL(2));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(4), COL(2));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(4), COL(3), COL(1), COL(8.0), COL(2.0));
ADD_ROW(result_table, COL(5), COL(1), COL(2), COL(4), COL(4), COL(1), COL(10.0), COL(2.5));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, 0, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_groupby_without_distinct1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
ObCollationType agg_cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(3), COL(1));
ADD_ROW(fake_table, COL(2), COL(null), COL(2));
ADD_ROW(fake_table, COL(3), COL(null), COL(2));
ADD_ROW(fake_table, COL(4), COL(2), COL(3));
ADD_ROW(fake_table, COL(5), COL(null), COL(3));
ADD_ROW(result_table, COL(1), COL(3), COL(1), COL(1), COL(3), COL(3), COL(3.0), COL(3.0));
ADD_ROW(result_table, COL(2), COL(null), COL(2), COL(0), COL(null), COL(null), COL(null), COL(null));
ADD_ROW(result_table, COL(4), COL(2), COL(3), COL(1), COL(2), COL(2), COL(2.0), COL(2.0));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, merge_groupby, 0, merge_groupby.get_column_count(), agg_cs_type);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
/*
TEST_F(ObMergeGroupbyTest, test_groupby_1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable &result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
ADD_ROW(fake_table, COL(1), COL(2), COL(1));
ADD_ROW(result_table, COL(1), COL(2), COL(1), COL(1.0), COL(2), COL(2), COL(2.0), COL(2.0));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT(ctx, result_table, merge_groupby);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_groupby_2)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT(ctx, result_table, merge_groupby);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_groupby_with_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ObFakeTable &fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable &result_table = TestAggregateFactory::get_result_table();
TestMergeGroupBy merge_groupby;
TestAggregateFactory::init(ctx, merge_groupby, 3, true);
//fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(1), COL(1));
ADD_ROW(fake_table, COL(3), COL(2), COL(1));
ADD_ROW(fake_table, COL(4), COL(2), COL(1));
ADD_ROW(fake_table, COL(5), COL(1), COL(2));
ADD_ROW(fake_table, COL(6), COL(1), COL(2));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(5), COL(2));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(2.0), COL(2), COL(1), COL(3.0), COL(1.5));
ADD_ROW(result_table, COL(5), COL(1), COL(2), COL(3.0), COL(5), COL(1), COL(9.0), COL(3.0));
TestAggregateFactory::open_operator(ctx, merge_groupby);
EXCEPT_RESULT(ctx, result_table, merge_groupby);
TestAggregateFactory::close_operator(ctx, merge_groupby);
}
TEST_F(ObMergeGroupbyTest, test_serialize_and_deserialize)
{
ObExecContext ctx;
ObPhysicalPlan physical_plan;
TestMergeGroupBy merge_groupby;
TestMergeGroupBy deserialize_op;
char bin_buf[1024] = {'\0'};
int64_t buf_len = 1024;
int64_t data_len = 0;
int64_t pos = 0;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
ASSERT_EQ(OB_SUCCESS, merge_groupby.serialize(bin_buf, buf_len, pos));
ASSERT_EQ(pos, merge_groupby.get_serialize_size());
deserialize_op.set_phy_plan(&physical_plan);
data_len = pos;
pos = 0;
ASSERT_EQ(OB_SUCCESS, deserialize_op.deserialize(bin_buf, data_len, pos));
ASSERT_EQ(0, strcmp(to_cstring(merge_groupby), to_cstring(deserialize_op)));
}
TEST_F(ObMergeGroupbyTest, test_invalid_argument)
{
ObExecContext ctx;
ObExecContext ctx1;
ObFakeTable fake_table;
TestMergeGroupBy merge_groupby;
const ObNewRow *row = NULL;
ASSERT_EQ(OB_INVALID_ARGUMENT, merge_groupby.open(ctx));
merge_groupby.reset();
ASSERT_EQ(OB_ERR_UNEXPECTED, merge_groupby.get_next_row(ctx, row));
merge_groupby.reset();
merge_groupby.set_id(0);
merge_groupby.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, ctx.init(3));
ASSERT_EQ(OB_NOT_INIT, merge_groupby.open(ctx));
merge_groupby.reset();
merge_groupby.set_id(0);
merge_groupby.set_column_count(3);
fake_table.set_id(1);
fake_table.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, merge_groupby.set_child(0, fake_table));
ASSERT_EQ(OB_SUCCESS, ctx1.init(3));
ASSERT_EQ(OB_COLUMN_GROUP_NOT_FOUND, merge_groupby.open(ctx1));
}
TEST_F(ObMergeGroupbyTest, test_invalid_argument1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
const ObNewRow *row = NULL;
ObFakeTable &fake_table = TestAggregateFactory::get_fake_table();
TestMergeGroupBy merge_groupby;
ObColumnExpression col_expr;
TestAggregateFactory::init(ctx, merge_groupby, 3, false);
//prepare rows, equal in the first row
ADD_ROW(fake_table, COL(1), COL(2), COL(1));
ADD_ROW(fake_table, COL(2), COL(2), COL(1));
merge_groupby.set_mem_size_limit(1);
TestAggregateFactory::open_operator(ctx, merge_groupby);
ASSERT_EQ(OB_EXCEED_MEM_LIMIT, merge_groupby.get_next_row(ctx, row));
merge_groupby.reset();
ASSERT_EQ(OB_NOT_INIT, merge_groupby.add_aggr_column(&col_expr));
}
*/
int main(int argc, char** argv)
{
init_global_memory_pool();
init_sql_factories();
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,367 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include "sql/ob_sql_init.h"
#include "sql/engine/aggregate/ob_scalar_aggregate.h"
#include "sql/engine/aggregate/ob_aggregate_test_utils.h"
#include "sql/engine/test_engine_util.h"
#include "storage/blocksstable/ob_data_file_prepare.h"
using namespace oceanbase::common;
using namespace oceanbase::sql;
using namespace oceanbase::blocksstable;
class TestScalarAggregateTest : public TestDataFilePrepare {
public:
TestScalarAggregateTest();
virtual ~TestScalarAggregateTest();
virtual void SetUp();
virtual void TearDown();
private:
// disallow copy
TestScalarAggregateTest(const TestScalarAggregateTest& other);
TestScalarAggregateTest& operator=(const TestScalarAggregateTest& other);
private:
// data members
};
TestScalarAggregateTest::TestScalarAggregateTest() : TestDataFilePrepare("TestDisk_scalar_groupby", 2 << 20, 5000)
{}
TestScalarAggregateTest::~TestScalarAggregateTest()
{}
void TestScalarAggregateTest::SetUp()
{
TestDataFilePrepare::SetUp();
int ret = ObTmpFileManager::get_instance().init();
ASSERT_EQ(OB_SUCCESS, ret);
}
void TestScalarAggregateTest::TearDown()
{
ObTmpFileManager::get_instance().destroy();
TestDataFilePrepare::TearDown();
}
class TestScalarAggregate : public ObScalarAggregate {
public:
TestScalarAggregate() : ObScalarAggregate(alloc_)
{}
~TestScalarAggregate()
{}
};
TEST_F(TestScalarAggregateTest, test_utf8mb4_bin)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
int64_t col_count = 3;
bool is_distinct = false;
bool is_number = false;
ObCollationType cs_type = CS_TYPE_UTF8MB4_BIN;
TestAggregateFactory::init(ctx, scalar_aggr_op, col_count, is_distinct, is_number, cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(2));
ADD_ROW(fake_table, COL(3), COL("t"), COL(3));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(4));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"), COL(4));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, scalar_aggr_op, col_count, scalar_aggr_op.get_column_count(), cs_type);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_utf8mb4_genaral_ci)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
int64_t col_count = 3;
bool is_distinct = false;
bool is_number = false;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, scalar_aggr_op, col_count, is_distinct, is_number, cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(2));
ADD_ROW(fake_table, COL(3), COL("t"), COL(3));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(4));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("t"), COL("r"), COL(3));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, scalar_aggr_op, col_count, scalar_aggr_op.get_column_count(), cs_type);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_utf8mb4_bin_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
int64_t col_count = 3;
bool is_distinct = true;
bool is_number = false;
ObCollationType cs_type = CS_TYPE_UTF8MB4_BIN;
TestAggregateFactory::init(ctx, scalar_aggr_op, col_count, is_distinct, is_number, cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(2));
ADD_ROW(fake_table, COL(3), COL("t"), COL(3));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(4));
ADD_ROW(fake_table, COL(5), COL("r"), COL(1));
ADD_ROW(fake_table, COL(6), COL("s"), COL(2));
ADD_ROW(fake_table, COL(7), COL("t"), COL(3));
ADD_ROW(fake_table, COL(8), COL("ß"), COL(4));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(4), COL("ß"), COL("r"), COL(4));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, scalar_aggr_op, col_count, scalar_aggr_op.get_column_count(), cs_type);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_utf8mb4_genaral_ci_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
int64_t col_count = 3;
bool is_distinct = true;
bool is_number = false;
ObCollationType cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
TestAggregateFactory::init(ctx, scalar_aggr_op, col_count, is_distinct, is_number, cs_type);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL("r"), COL(1));
ADD_ROW(fake_table, COL(2), COL("s"), COL(2));
ADD_ROW(fake_table, COL(3), COL("t"), COL(3));
ADD_ROW(fake_table, COL(4), COL("ß"), COL(4));
ADD_ROW(fake_table, COL(5), COL("r"), COL(1));
ADD_ROW(fake_table, COL(6), COL("s"), COL(2));
ADD_ROW(fake_table, COL(7), COL("t"), COL(3));
ADD_ROW(fake_table, COL(8), COL("ß"), COL(4));
ADD_ROW(result_table, COL(0), COL(0), COL(0), COL(3), COL("t"), COL("r"), COL(3));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, scalar_aggr_op, col_count, scalar_aggr_op.get_column_count(), cs_type);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_aggr_without_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
TestAggregateFactory::init(ctx, scalar_aggr_op, 3, false);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(2), COL(2));
ADD_ROW(fake_table, COL(5), COL(2), COL(3));
ADD_ROW(fake_table, COL(4), COL(3), COL(4));
ADD_ROW(fake_table, COL(3), COL(1), COL(3));
ADD_ROW(fake_table, COL(6), COL(2), COL(1));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(4), COL(4));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(8), COL(4), COL(1), COL(18.0), COL(2.25));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT(ctx, result_table, scalar_aggr_op, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_aggr_with_distinct)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
TestAggregateFactory::init(ctx, scalar_aggr_op, 3, true);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(fake_table, COL(1), COL(1), COL(1));
ADD_ROW(fake_table, COL(2), COL(1), COL(1));
ADD_ROW(fake_table, COL(3), COL(2), COL(1));
ADD_ROW(fake_table, COL(4), COL(2), COL(1));
ADD_ROW(fake_table, COL(5), COL(1), COL(2));
ADD_ROW(fake_table, COL(6), COL(1), COL(2));
ADD_ROW(fake_table, COL(7), COL(3), COL(2));
ADD_ROW(fake_table, COL(8), COL(5), COL(2));
ADD_ROW(result_table, COL(1), COL(1), COL(1), COL(4), COL(5), COL(1), COL(11.0), COL(2.75), COL(4));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT(ctx, result_table, scalar_aggr_op, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_aggr_empty_set)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
TestAggregateFactory::init(ctx, scalar_aggr_op, 3, true);
// fake table: index_col(primary key), aggr_col, groupby_col
ADD_ROW(result_table,
COL(null),
COL(null),
COL(null),
COL(0),
COL(null),
COL(null),
COL(0),
COL(null),
COL(null),
COL(0));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT(ctx, result_table, scalar_aggr_op, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_aggr_bug_6131507)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
ObFakeTable& result_table = TestAggregateFactory::get_result_table();
TestScalarAggregate scalar_aggr_op;
TestAggregateFactory::init(ctx, scalar_aggr_op, 3);
// fake table: c, b, a(primary key)
ADD_ROW(fake_table, COL(null), COL(4), COL(1));
ADD_ROW(fake_table, COL(null), COL(3), COL(3));
ADD_ROW(fake_table, COL(null), COL(3), COL(4));
ADD_ROW(result_table,
COL(null),
COL(4),
COL(1),
COL(null),
COL(3.33333333333333333333333333333333333333333333),
COL(2.66666666666666666666666666666666666666666667));
TestAggregateFactory::open_operator(ctx, scalar_aggr_op);
EXCEPT_RESULT_WITH_IDX(ctx, result_table, scalar_aggr_op, 0, 3, CS_TYPE_UTF8MB4_BIN);
TestAggregateFactory::close_operator(ctx, scalar_aggr_op);
}
TEST_F(TestScalarAggregateTest, test_invalid_argument)
{
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObExecContext ctx1;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx1));
ObFakeTable fake_table;
TestScalarAggregate scalar_aggr_op;
const ObNewRow* row = NULL;
ASSERT_EQ(OB_NOT_INIT, scalar_aggr_op.open(ctx));
scalar_aggr_op.reset();
ASSERT_EQ(OB_ERR_UNEXPECTED, scalar_aggr_op.get_next_row(ctx, row));
scalar_aggr_op.reset();
scalar_aggr_op.set_id(0);
scalar_aggr_op.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, ctx.init_phy_op(3));
ASSERT_EQ(OB_NOT_INIT, scalar_aggr_op.open(ctx));
scalar_aggr_op.reset();
scalar_aggr_op.set_id(4);
scalar_aggr_op.set_column_count(3);
fake_table.set_id(1);
fake_table.set_column_count(3);
ASSERT_EQ(OB_SUCCESS, scalar_aggr_op.set_child(0, fake_table));
ASSERT_EQ(OB_SUCCESS, ctx1.init_phy_op(3));
ASSERT_EQ(OB_ERR_UNEXPECTED, scalar_aggr_op.open(ctx1));
}
TEST_F(TestScalarAggregateTest, test_invalid_argument1)
{
int ret = OB_SUCCESS;
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
const ObNewRow* row = NULL;
ObFakeTable& fake_table = TestAggregateFactory::get_fake_table();
TestScalarAggregate scalar_aggr_op;
ObArenaAllocator alloc;
ObAggregateExpression col_expr(alloc);
TestAggregateFactory::init(ctx, scalar_aggr_op, 3, false);
// prepare rows, equal in the first row
ADD_ROW(fake_table, COL(1), COL("123"), COL(1));
ADD_ROW(fake_table, COL(2), COL("456"), COL(1));
scalar_aggr_op.set_mem_size_limit(1);
ASSERT_EQ(OB_SUCCESS, scalar_aggr_op.open(ctx));
ASSERT_EQ(OB_EXCEED_MEM_LIMIT, scalar_aggr_op.get_next_row(ctx, row));
scalar_aggr_op.reset();
// ASSERT_EQ(OB_NOT_INIT, scalar_aggr_op.add_aggr_column(&col_expr));
}
TEST_F(TestScalarAggregateTest, test_serialize_and_deserialize)
{
ObExecContext ctx;
ASSERT_EQ(OB_SUCCESS, create_test_session(ctx));
ObPhysicalPlan physical_plan;
TestScalarAggregate scalar_aggr_op;
TestScalarAggregate deserialize_op;
char bin_buf[1024] = {'\0'};
int64_t buf_len = 1024;
int64_t data_len = 0;
int64_t pos = 0;
TestAggregateFactory::init(ctx, scalar_aggr_op, 3, false);
ASSERT_EQ(OB_SUCCESS, scalar_aggr_op.serialize(bin_buf, buf_len, pos));
ASSERT_EQ(pos, scalar_aggr_op.get_serialize_size());
deserialize_op.set_phy_plan(&physical_plan);
data_len = pos;
pos = 0;
ASSERT_EQ(OB_SUCCESS, deserialize_op.deserialize(bin_buf, data_len, pos));
ASSERT_EQ(0, strcmp(to_cstring(scalar_aggr_op), to_cstring(deserialize_op)));
}
int main(int argc, char** argv)
{
init_global_memory_pool();
init_sql_factories();
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}