Co-authored-by: wangt1xiuyi <13547954130@163.com> Co-authored-by: yangqise7en <877793735@qq.com> Co-authored-by: Zach41 <zach_41@163.com>
170 lines
5.3 KiB
C++
170 lines
5.3 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX STORAGE
|
|
#include "ob_block_row_store.h"
|
|
#include "lib/stat/ob_diagnose_info.h"
|
|
#include "common/sql_mode/ob_sql_mode_utils.h"
|
|
#include "sql/engine/basic/ob_pushdown_filter.h"
|
|
#include "storage/ob_i_store.h"
|
|
#include "storage/blocksstable/encoding/ob_micro_block_decoder.h"
|
|
#include "storage/blocksstable/ob_micro_block_reader.h"
|
|
#include "storage/blocksstable/ob_micro_block_row_scanner.h"
|
|
#include "storage/access/ob_table_access_context.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace common;
|
|
using namespace share;
|
|
using namespace blocksstable;
|
|
namespace storage
|
|
{
|
|
|
|
ObBlockRowStore::ObBlockRowStore(ObTableAccessContext &context)
|
|
: is_inited_(false),
|
|
pd_filter_info_(),
|
|
context_(context),
|
|
can_blockscan_(false),
|
|
filter_applied_(false),
|
|
disabled_(false)
|
|
{}
|
|
|
|
ObBlockRowStore::~ObBlockRowStore()
|
|
{
|
|
}
|
|
|
|
void ObBlockRowStore::reset()
|
|
{
|
|
is_inited_ = false;
|
|
can_blockscan_ = false;
|
|
filter_applied_ = false;
|
|
pd_filter_info_.reset();
|
|
disabled_ = false;
|
|
}
|
|
|
|
void ObBlockRowStore::reuse()
|
|
{
|
|
can_blockscan_ = false;
|
|
filter_applied_ = false;
|
|
disabled_ = false;
|
|
}
|
|
|
|
int ObBlockRowStore::init(const ObTableAccessParam ¶m)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (IS_INIT) {
|
|
ret = OB_INIT_TWICE;
|
|
LOG_WARN("ObBlockRowStore init twice", K(ret));
|
|
} else if (OB_ISNULL(context_.stmt_allocator_)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("Invalid argument to init store pushdown filter", K(ret));
|
|
} else if (OB_FAIL(pd_filter_info_.init(param.iter_param_, *context_.stmt_allocator_))) {
|
|
LOG_WARN("Fail to init pd filter info", K(ret));
|
|
} else {
|
|
is_inited_ = true;
|
|
}
|
|
|
|
if (IS_NOT_INIT) {
|
|
reset();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObBlockRowStore::apply_blockscan(
|
|
blocksstable::ObIMicroBlockRowScanner µ_scanner,
|
|
const bool can_pushdown,
|
|
ObTableStoreStat &table_store_stat)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t access_count = micro_scanner.get_access_cnt();
|
|
if (IS_NOT_INIT) {
|
|
ret = OB_NOT_INIT;
|
|
LOG_WARN("ObBlockRowStore is not inited", K(ret), K(*this));
|
|
} else if (!pd_filter_info_.is_pd_filter_ || !can_pushdown) {
|
|
filter_applied_ = false;
|
|
} else if (nullptr == pd_filter_info_.filter_) {
|
|
// nothing to do
|
|
filter_applied_ = true;
|
|
} else if (OB_FAIL(micro_scanner.filter_micro_block_in_blockscan(pd_filter_info_))) {
|
|
LOG_WARN("Failed to apply pushdown filter in block reader", K(ret), K(*this));
|
|
} else {
|
|
filter_applied_ = true;
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
// Check pushdown filter successed
|
|
can_blockscan_ = true;
|
|
++table_store_stat.pushdown_micro_access_cnt_;
|
|
table_store_stat.pushdown_row_access_cnt_ += access_count;
|
|
if (!filter_applied_ || nullptr == pd_filter_info_.filter_) {
|
|
table_store_stat.pushdown_row_select_cnt_ += access_count;
|
|
} else {
|
|
int64_t select_cnt = pd_filter_info_.filter_->get_result()->popcnt();
|
|
table_store_stat.pushdown_row_select_cnt_ += select_cnt;
|
|
EVENT_ADD(ObStatEventIds::PUSHDOWN_STORAGE_FILTER_ROW_CNT, select_cnt);
|
|
}
|
|
EVENT_ADD(ObStatEventIds::BLOCKSCAN_ROW_CNT, access_count);
|
|
LOG_DEBUG("[PUSHDOWN] apply blockscan succ", K(access_count), KPC(pd_filter_info_.filter_), K(*this));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObBlockRowStore::get_filter_result(ObFilterResult &res)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
res.bitmap_ = nullptr;
|
|
res.filter_start_ = pd_filter_info_.start_;
|
|
if (nullptr == pd_filter_info_.filter_ || !filter_applied_) {
|
|
} else if (OB_ISNULL(res.bitmap_ = pd_filter_info_.filter_->get_result())) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("Unexpected null filter bitmap", K(ret));
|
|
} else if (res.bitmap_->is_all_true()) {
|
|
res.bitmap_ = nullptr;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObBlockRowStore::open(const ObTableIterParam &iter_param)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const bool need_padding = is_pad_char_to_full_length(context_.sql_mode_);
|
|
if (IS_NOT_INIT) {
|
|
ret = OB_NOT_INIT;
|
|
LOG_WARN("Not init", K(ret));
|
|
} else if (OB_UNLIKELY(!iter_param.is_valid() ||
|
|
nullptr == iter_param.get_col_params() ||
|
|
nullptr == iter_param.out_cols_project_)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("Invalid argument to init store pushdown filter", K(ret), K(iter_param));
|
|
} else if (nullptr == pd_filter_info_.filter_) {
|
|
// nothing to do
|
|
} else {
|
|
if (iter_param.is_use_column_store()) {
|
|
if (OB_FAIL(pd_filter_info_.filter_->init_co_filter_param(iter_param, need_padding))) {
|
|
LOG_WARN("Failed to init pushdown filter executor", K(ret));
|
|
}
|
|
} else if (OB_FAIL(pd_filter_info_.filter_->init_filter_param(
|
|
*iter_param.get_col_params(), *iter_param.out_cols_project_, need_padding))) {
|
|
LOG_WARN("Failed to init pushdown filter executor", K(ret));
|
|
}
|
|
|
|
if (OB_FAIL(ret)) {
|
|
} else if (OB_FAIL(pd_filter_info_.filter_->init_evaluated_datums())) {
|
|
LOG_WARN("Failed to init pushdown filter evaluated datums", K(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
}
|