Files
oceanbase/src/sql/engine/table/ob_mv_table_scan.cpp
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

170 lines
6.4 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 SQL_OPT
#include "sql/engine/table/ob_mv_table_scan.h"
using namespace oceanbase;
using namespace common;
using namespace storage;
using namespace sql;
ObPhyOperatorType ObMVTableScanInput::get_phy_op_type() const
{
return PHY_MV_TABLE_SCAN;
}
ObMVTableScan::ObMVTableScan(common::ObIAllocator& allocator)
: ObTableScan(allocator), right_table_param_(allocator), right_table_location_key_(OB_INVALID_ID)
{}
inline int ObMVTableScan::init_op_ctx(ObExecContext& ctx) const
{
int ret = OB_SUCCESS;
ObPhyOperatorCtx* op_ctx = NULL;
ObTableScanInput* scan_input = NULL;
if (OB_ISNULL(scan_input = GET_PHY_OP_INPUT(ObTableScanInput, ctx, get_id()))) {
if (OB_FAIL(CREATE_PHY_OP_INPUT(ObMVTableScanInput, ctx, get_id(), get_type(), scan_input))) {
LOG_WARN("fail to create table scan input", K(ret), "op_id", get_id(), "op_type", get_type());
} else {
scan_input->set_location_idx(0);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(CREATE_PHY_OPERATOR_CTX(ObMVTableScanCtx, ctx, get_id(), get_type(), op_ctx))) {
LOG_WARN("create physical operator context failed", K(ret), K(get_type()));
} else if (OB_ISNULL(op_ctx)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("operator context is null");
} else if (OB_FAIL(init_cur_row(*op_ctx, false))) {
LOG_WARN("init current row failed", K(ret));
}
}
return ret;
}
int ObMVTableScan::prepare_scan_param(ObExecContext& ctx) const
{
int ret = OB_SUCCESS;
ObSQLSessionInfo* my_session = NULL;
ObMVTableScanCtx* scan_ctx = NULL;
if (OB_ISNULL(scan_ctx = GET_PHY_OPERATOR_CTX(ObMVTableScanCtx, ctx, get_id()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get op ctx", K(ret));
} else if (OB_ISNULL(my_session = GET_MY_SESSION(ctx))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get my session", K(ret));
} else if (OB_FAIL(ObTableScan::prepare_scan_param(ctx))) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to do prepare_scan_param", K(ret));
}
} else {
scan_ctx->right_scan_param_.trans_desc_ = &my_session->get_trans_desc();
const ObPhyTableLocation* table_loc = NULL;
ObTaskExecutorCtx* executor_ctx = NULL;
if (OB_ISNULL(executor_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get task executor ctx", K(ret));
} else if (OB_FAIL(ObTaskExecutorCtxUtil::get_phy_table_location(
*executor_ctx, right_table_location_key_, right_table_location_key_, table_loc))) {
LOG_WARN("fail to get mv right table location", K(ret), K(right_table_location_key_));
} else if (OB_ISNULL(table_loc)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("table location is NULL", K(ret));
} else {
const share::ObPartitionReplicaLocation& part_loc = table_loc->get_partition_location_list().at(0);
if (OB_FAIL(part_loc.get_partition_key(scan_ctx->right_scan_param_.pkey_))) {
LOG_WARN("get partition key fail", K(ret), K(part_loc));
}
}
}
return ret;
}
OB_SERIALIZE_MEMBER((ObMVTableScan, ObTableScan), right_table_param_, right_table_location_key_);
void ObMVTableScan::reset()
{
ObTableScan::reset();
right_table_param_.reset();
right_table_location_key_ = OB_INVALID_ID;
}
void ObMVTableScan::reuse()
{
ObTableScan::reuse();
right_table_param_.reset();
right_table_location_key_ = OB_INVALID_ID;
}
int ObMVTableScan::do_table_scan(ObExecContext& ctx, bool is_rescan) const
{
int ret = OB_SUCCESS;
ObTableScanInput* scan_input = NULL;
ObMVTableScanCtx* scan_ctx = NULL;
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
ObSQLSessionInfo* my_session = NULL;
if (OB_ISNULL(my_session = GET_MY_SESSION(ctx))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get my session", K(ret));
} else if (OB_ISNULL(scan_input = GET_PHY_OP_INPUT(ObTableScanInput, ctx, get_id()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get op input", K(ret));
} else if (OB_ISNULL(scan_ctx = GET_PHY_OPERATOR_CTX(ObMVTableScanCtx, ctx, get_id()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get op ctx", K(ret));
} else if (OB_FAIL(prepare(ctx, is_rescan))) { // prepare scan input param
LOG_WARN("fail to prepare scan param", K(ret));
}
/* step 1 */
if (OB_SUCC(ret)) {
scan_ctx->output_row_count_ = 0;
scan_ctx->scan_param_.key_ranges_.reset();
scan_ctx->scan_param_.scan_flag_.join_type_ = INNER_JOIN;
scan_ctx->scan_param_.table_param_ = &table_param_;
scan_ctx->right_scan_param_.table_param_ = &right_table_param_;
scan_ctx->right_scan_param_.scan_flag_.join_type_ = INNER_JOIN;
scan_ctx->right_scan_param_.timeout_ = scan_ctx->scan_param_.timeout_;
scan_ctx->right_scan_param_.schema_version_ = scan_ctx->scan_param_.schema_version_;
scan_ctx->right_scan_param_.index_id_ = right_table_param_.get_table_id();
scan_ctx->right_scan_param_.reserved_cell_count_ = output_column_ids_.count();
scan_ctx->right_scan_param_.column_ids_.reset();
scan_ctx->right_scan_param_.column_ids_.assign(output_column_ids_);
for (int64_t i = 0; OB_SUCC(ret) && i < scan_input->key_ranges_.count(); ++i) {
if (OB_FAIL(scan_ctx->scan_param_.key_ranges_.push_back(scan_input->key_ranges_.at(i)))) {
LOG_WARN("fail to push back key range", K(ret), K(i));
}
}
}
if (OB_SUCC(ret)) {
ObIDataAccessService* das = NULL;
if (OB_FAIL(get_partition_service(task_exec_ctx, das))) {
LOG_WARN("fail to get partition service", K(ret));
} else if (OB_FAIL(das->join_mv_scan(scan_ctx->scan_param_, scan_ctx->right_scan_param_, scan_ctx->result_))) {
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
LOG_WARN("fail to scan table", K(scan_ctx->scan_param_), K(ret));
}
} else {
LOG_DEBUG("table_scan begin", K(scan_ctx->scan_param_), K(*scan_ctx->result_), "op_id", get_id());
}
}
if (OB_SUCC(ret)) {
ret = sim_err(my_session);
}
return ret;
}