patch 4.0
This commit is contained in:
@ -15,42 +15,209 @@
|
||||
#include "sql/engine/subquery/ob_subplan_filter_op.h"
|
||||
#include "common/row/ob_row_iterator.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "pl/ob_pl_stmt.h"
|
||||
#include "pl/ob_pl_user_type.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/ob_spi.h"
|
||||
#include "sql/engine/subquery/ob_subplan_filter_op.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
OB_SERIALIZE_MEMBER(
|
||||
(ObExprSubQueryRef, ObExprOperator), result_is_scalar_, scalar_result_type_, subquery_idx_, row_desc_);
|
||||
namespace sql
|
||||
{
|
||||
OB_SERIALIZE_MEMBER(ObExprSubQueryRef::ExtraInfo,
|
||||
is_cursor_,
|
||||
scalar_result_type_,
|
||||
row_desc_);
|
||||
|
||||
ObExprSubQueryRef::ObExprSubQueryRef(ObIAllocator& alloc)
|
||||
: ObExprOperator(alloc, T_REF_QUERY, N_REF_QUERY, 0, NOT_ROW_DIMENSION),
|
||||
result_is_scalar_(false),
|
||||
scalar_result_type_(alloc),
|
||||
subquery_idx_(OB_INVALID_INDEX),
|
||||
row_desc_(alloc)
|
||||
{}
|
||||
|
||||
ObExprSubQueryRef::~ObExprSubQueryRef()
|
||||
{}
|
||||
|
||||
int ObExprSubQueryRef::assign(const ObExprOperator& other)
|
||||
int ObExprSubQueryRef::Extra::assign(const Extra &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObExprSubQueryRef* tmp_other = dynamic_cast<const ObExprSubQueryRef*>(&other);
|
||||
op_id_ = other.op_id_;
|
||||
iter_idx_ = other.iter_idx_;
|
||||
is_scalar_ = other.is_scalar_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObExprSubQueryRef::ExtraInfo::reset()
|
||||
{
|
||||
is_cursor_ = 0;
|
||||
row_desc_.reset();
|
||||
scalar_result_type_.reset();
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::ExtraInfo::assign(const ExtraInfo &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_cursor_ = other.is_cursor_;
|
||||
OZ (scalar_result_type_.assign(other.scalar_result_type_));
|
||||
OZ (row_desc_.assign(other.row_desc_));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::ExtraInfo::init_cursor_info(ObIAllocator *allocator,
|
||||
const ObQueryRefRawExpr &expr,
|
||||
const ObExprOperatorType type,
|
||||
ObExpr &rt_expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ExtraInfo *cursor_info = NULL;
|
||||
void *buf = NULL;
|
||||
if (OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("allocator is null", K(ret), K(allocator));
|
||||
} else if (OB_ISNULL(buf = allocator->alloc(sizeof(ExtraInfo)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc memory", K(ret));
|
||||
} else {
|
||||
cursor_info = new(buf) ExtraInfo(*allocator, type);
|
||||
bool result_is_scalar = (expr.get_output_column() == 1 && !expr.is_set());
|
||||
if (result_is_scalar) {
|
||||
cursor_info->scalar_result_type_ = expr.get_result_type();
|
||||
}
|
||||
Extra::get_info(rt_expr).is_scalar_ = result_is_scalar;
|
||||
Extra::get_info(rt_expr).iter_idx_ = expr.get_ref_id() - 1;
|
||||
cursor_info->is_cursor_ = expr.is_cursor();
|
||||
if (OB_FAIL(cursor_info->row_desc_.reserve(expr.get_column_types().count()))) {
|
||||
LOG_WARN("fail to init row_desc_", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < expr.get_column_types().count(); ++i) {
|
||||
ObDataType type;
|
||||
type.set_meta_type(expr.get_column_types().at(i));
|
||||
type.set_accuracy(expr.get_column_types().at(i).get_accuracy());
|
||||
OZ (cursor_info->row_desc_.push_back(type));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
rt_expr.extra_info_ = cursor_info;
|
||||
LOG_DEBUG("succ init_cursor_info", KPC(cursor_info));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::ExtraInfo::deep_copy(common::ObIAllocator &allocator,
|
||||
const ObExprOperatorType type,
|
||||
ObIExprExtraInfo *&copied_info) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ExtraInfo *copied_cursor_info = NULL;
|
||||
if (OB_FAIL(ObExprExtraInfoFactory::alloc(allocator, type, copied_info))) {
|
||||
LOG_WARN("failed to alloc expr extra info", K(ret));
|
||||
} else if (OB_ISNULL(copied_cursor_info = static_cast<ExtraInfo *>(copied_info))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected error", K(ret));
|
||||
} else if (OB_FAIL(copied_cursor_info->row_desc_.prepare_allocate(row_desc_.count()))) {
|
||||
LOG_WARN("failed to prepare allocate", K(ret));
|
||||
} else {
|
||||
copied_cursor_info->is_cursor_ = is_cursor_;
|
||||
for (int i = 0; OB_SUCC(ret) && i < row_desc_.count(); i++) {
|
||||
copied_cursor_info->row_desc_.at(i) = row_desc_.at(i);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObExprSubQueryRef)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObExprOperator::serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("fail to serialize ObExprOperator", K(buf_len), K(pos), K(ret));
|
||||
}
|
||||
bool is_scalar = static_cast<bool>(extra_.is_scalar_);
|
||||
int64_t iter_idx = static_cast<int64_t>(extra_.iter_idx_);
|
||||
LST_DO_CODE(OB_UNIS_ENCODE,
|
||||
is_scalar,
|
||||
extra_info_.scalar_result_type_,
|
||||
iter_idx,
|
||||
extra_info_.is_cursor_,
|
||||
extra_info_.row_desc_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObExprSubQueryRef)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObExprOperator::deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("fail to serialize ObExprOperator", K(data_len), K(pos), K(ret));
|
||||
}
|
||||
bool is_scalar = false;
|
||||
int64_t iter_idx = 0;
|
||||
LST_DO_CODE(OB_UNIS_DECODE,
|
||||
is_scalar,
|
||||
extra_info_.scalar_result_type_,
|
||||
iter_idx,
|
||||
extra_info_.is_cursor_,
|
||||
extra_info_.row_desc_);
|
||||
if (OB_SUCC(ret)) {
|
||||
extra_.is_scalar_ = static_cast<uint16_t>(is_scalar);
|
||||
extra_.iter_idx_ = static_cast<uint16_t>(iter_idx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObExprSubQueryRef)
|
||||
{
|
||||
int64_t len = 0;
|
||||
bool is_scalar = static_cast<bool>(extra_.is_scalar_);
|
||||
int64_t iter_idx = static_cast<int64_t>(extra_.iter_idx_);
|
||||
len += ObExprOperator::get_serialize_size();
|
||||
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
||||
is_scalar,
|
||||
extra_info_.scalar_result_type_,
|
||||
iter_idx,
|
||||
extra_info_.is_cursor_,
|
||||
extra_info_.row_desc_);
|
||||
return len;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::ObExprSubQueryRefCtx::add_cursor_info(
|
||||
pl::ObPLCursorInfo *cursor_info, sql::ObSQLSessionInfo *session_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CK (OB_NOT_NULL(session_info));
|
||||
CK (OB_NOT_NULL(cursor_info));
|
||||
OX (session_info_ = session_info);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (NULL == cursor_info_) {
|
||||
OX (cursor_info_ = cursor_info);
|
||||
} else if (cursor_info_ != cursor_info) {
|
||||
OZ (cursor_info_->close(*session_info_));
|
||||
OX (cursor_info_->~ObPLCursorInfo());
|
||||
OX (cursor_info_ = cursor_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObExprSubQueryRef::ObExprSubQueryRef(ObIAllocator &alloc)
|
||||
: ObExprOperator(alloc, T_REF_QUERY,
|
||||
N_REF_QUERY,
|
||||
0,
|
||||
NOT_ROW_DIMENSION,
|
||||
INTERNAL_IN_MYSQL_MODE,
|
||||
INTERNAL_IN_ORACLE_MODE),
|
||||
extra_(),
|
||||
extra_info_(alloc, T_REF_QUERY)
|
||||
{
|
||||
}
|
||||
|
||||
ObExprSubQueryRef::~ObExprSubQueryRef()
|
||||
{
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::assign(const ObExprOperator &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObExprSubQueryRef *tmp_other = static_cast<const ObExprSubQueryRef *>(&other);
|
||||
if (OB_UNLIKELY(NULL == tmp_other)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument. wrong type for other", K(ret), K(other));
|
||||
} else if (this != tmp_other) {
|
||||
if (OB_FAIL(ObExprOperator::assign(other))) {
|
||||
LOG_WARN("copy in Base class ObExprOperator failed", K(ret));
|
||||
} else if (OB_FAIL(scalar_result_type_.assign(tmp_other->scalar_result_type_))) {
|
||||
LOG_WARN("copy scalar_result_type_ failed", K(ret));
|
||||
} else if (OB_FAIL(row_desc_.assign(tmp_other->row_desc_))) {
|
||||
LOG_WARN("copy accuracy desc failed", K(ret));
|
||||
} else {
|
||||
this->result_is_scalar_ = tmp_other->result_is_scalar_;
|
||||
this->subquery_idx_ = tmp_other->subquery_idx_;
|
||||
OZ (extra_.assign(tmp_other->extra_));
|
||||
OZ (extra_info_.assign(tmp_other->extra_info_));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -58,19 +225,20 @@ int ObExprSubQueryRef::assign(const ObExprOperator& other)
|
||||
|
||||
void ObExprSubQueryRef::reset()
|
||||
{
|
||||
result_is_scalar_ = false;
|
||||
subquery_idx_ = OB_INVALID_INDEX;
|
||||
result_type_.set_null();
|
||||
row_desc_.reset();
|
||||
extra_.reset();
|
||||
extra_info_.reset();
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::calc_result_type0(ObExprResType& type, ObExprTypeCtx& type_ctx) const
|
||||
int ObExprSubQueryRef::calc_result_type0(ObExprResType &type, ObExprTypeCtx &type_ctx) const
|
||||
{
|
||||
UNUSED(type_ctx);
|
||||
if (result_is_scalar_) {
|
||||
type = scalar_result_type_;
|
||||
if (extra_info_.is_cursor_) {
|
||||
type.set_ext();
|
||||
} else if (extra_.is_scalar_) {
|
||||
//subquery的结果是一个标量,那么返回类型是标量的实际返回类型
|
||||
type = extra_info_.scalar_result_type_;
|
||||
} else {
|
||||
// for static typing engine, we return ObExpr::extra_
|
||||
//subquery的结果是一个向量或者集合,那么返回类型是其迭代器index的数据类型
|
||||
type.set_int();
|
||||
type.set_scale(ObAccuracy::DDL_DEFAULT_ACCURACY[ObIntType].scale_);
|
||||
type.set_precision(ObAccuracy::DDL_DEFAULT_ACCURACY[ObIntType].precision_);
|
||||
@ -78,113 +246,155 @@ int ObExprSubQueryRef::calc_result_type0(ObExprResType& type, ObExprTypeCtx& typ
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::calc_result0(ObObj& result, ObExprCtx& expr_ctx) const
|
||||
void ObExprSubQueryRef::set_scalar_result_type(const ObExprResType &result_type)
|
||||
{
|
||||
extra_info_.scalar_result_type_ = result_type;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::cg_expr(
|
||||
ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObNewRow* row = NULL;
|
||||
ObNewRowIterator* row_iter = NULL;
|
||||
ObIArray<ObNewRowIterator*>* row_iters = expr_ctx.subplan_iters_;
|
||||
if (OB_ISNULL(row_iters) || OB_ISNULL(expr_ctx.calc_buf_)) {
|
||||
const ObQueryRefRawExpr *expr = static_cast<const ObQueryRefRawExpr *>(&raw_expr);
|
||||
CK (OB_NOT_NULL(expr));
|
||||
OZ (ExtraInfo::init_cursor_info(op_cg_ctx.allocator_, *expr, type_, rt_expr));
|
||||
OX (rt_expr.eval_func_ = &expr_eval);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::convert_datum_to_obj(
|
||||
ObEvalCtx &ctx, ObSubQueryIterator &iter, ObIAllocator &allocator, ObNewRow &row)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (iter.get_output().count() > 0 && NULL == row.cells_) {
|
||||
if (OB_ISNULL(row.cells_ = static_cast<ObObj *>(
|
||||
allocator.alloc(sizeof(ObObj) * iter.get_output().count())))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("allocate memory failed", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; i < iter.get_output().count(); i++) {
|
||||
new (&row.cells_[i]) ObObj();
|
||||
}
|
||||
row.count_ = iter.get_output().count();
|
||||
row.projector_size_ = 0;
|
||||
row.projector_ = NULL;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < iter.get_output().count(); i++) {
|
||||
ObDatum *datum = NULL;
|
||||
ObExpr *expr = iter.get_output().at(i);
|
||||
if (OB_FAIL(expr->eval(ctx, datum))) {
|
||||
LOG_WARN("expr evaluate failed", K(ret));
|
||||
} else if (OB_FAIL(datum->to_obj(
|
||||
row.cells_[i], expr->obj_meta_, expr->obj_datum_map_))) {
|
||||
LOG_WARN("convert datum to obj failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::expr_eval(
|
||||
const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const Extra &extra = Extra::get_info(expr);
|
||||
const ExtraInfo *extra_info = static_cast<ExtraInfo *>(expr.extra_info_);
|
||||
ObDatum *datum = NULL;
|
||||
ObSubQueryIterator *iter = NULL;
|
||||
//对所有iter 进行reset操作
|
||||
if (OB_ISNULL(extra_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_UNLIKELY(subquery_idx_ < 0 || subquery_idx_ >= row_iters->count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("subquery row iterator does not exist", "row_iters_count", row_iters->count(), K_(subquery_idx));
|
||||
} else if (OB_ISNULL(row_iter = row_iters->at(subquery_idx_))) {
|
||||
LOG_WARN("extra info is null", K(ret));
|
||||
} else if (OB_FAIL(get_subquery_iter(ctx, extra, iter))) {
|
||||
LOG_WARN("get sub query iterator failed", K(ret), K(extra));
|
||||
} else if (OB_ISNULL(iter)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else {
|
||||
row_iter->reset();
|
||||
LOG_WARN("null iter returned", K(ret));
|
||||
} else if (OB_FAIL(iter->rewind())) {
|
||||
LOG_WARN("filter to rewind subquery iterator", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
/*do nothing*/
|
||||
} else if (result_is_scalar_) {
|
||||
// subquery result is a scalar obj
|
||||
bool iter_end = false;
|
||||
if (OB_FAIL(row_iter->get_next_row(row))) {
|
||||
if (OB_LIKELY(OB_ITER_END == ret)) {
|
||||
ret = OB_SUCCESS;
|
||||
iter_end = true;
|
||||
result.set_null();
|
||||
} else {
|
||||
LOG_WARN("get next row from row iterator failed", K(ret));
|
||||
}
|
||||
} else if (OB_ISNULL(row)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("row is null", K(ret));
|
||||
} else if (OB_UNLIKELY(1 != row->get_count())) {
|
||||
// not a scalar obj
|
||||
ret = OB_ERR_INVALID_COLUMN_NUM;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_COLUMN_NUM, (int64_t)1);
|
||||
} else if (OB_FAIL(ob_write_obj(*expr_ctx.calc_buf_, row->get_cell(0), result))) {
|
||||
LOG_WARN("deep copy obj failed", K(ret), K(row->get_cell(0)));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (iter_end) {
|
||||
// it's iter end, don't get next row
|
||||
// #bug29851474
|
||||
} else if (OB_UNLIKELY(OB_SUCCESS == (ret = row_iter->get_next_row(row)))) {
|
||||
LOG_WARN("subquery too many rows", K(ret));
|
||||
ret = OB_SUBQUERY_TOO_MANY_ROW;
|
||||
} else if (OB_LIKELY(OB_ITER_END == ret)) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("get next row from row iterator failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// subquery result is a row or a set, so return the index of subquery row iterator
|
||||
result.set_int(subquery_idx_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObExprSubQueryRef::set_scalar_result_type(const ObExprResType& result_type)
|
||||
{
|
||||
scalar_result_type_ = result_type;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::cg_expr(ObExprCGCtx&, const ObRawExpr&, ObExpr& rt_expr) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ExtraInfo::get_info(rt_expr).is_scalar_ = result_is_scalar_;
|
||||
CK(OB_INVALID_INDEX != subquery_idx_);
|
||||
ExtraInfo::get_info(rt_expr).iter_idx_ = subquery_idx_;
|
||||
rt_expr.eval_func_ = &expr_eval;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::expr_eval(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ExtraInfo& info = ExtraInfo::get_info(expr);
|
||||
if (info.is_scalar_) {
|
||||
ObDatum* datum = NULL;
|
||||
ObSubQueryIterator* iter = NULL;
|
||||
if (OB_FAIL(get_subquery_iter(ctx, info, iter))) {
|
||||
LOG_WARN("get sub query iterator failed", K(ret), K(info));
|
||||
} else if (OB_ISNULL(iter)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("null iter returned", K(ret));
|
||||
} else if (1 != iter->get_output().count()) {
|
||||
// not a scalar obj
|
||||
} else if (extra.is_scalar_) {
|
||||
if (1 != iter->get_output().count()) {
|
||||
//not a scalar obj
|
||||
ret = OB_ERR_INVALID_COLUMN_NUM;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_COLUMN_NUM, 1L);
|
||||
} else {
|
||||
iter->reset();
|
||||
if (OB_FAIL(iter->get_next_row())) {
|
||||
bool iter_end = false;
|
||||
bool found_in_hash_map = false;
|
||||
bool is_hash_enabled = iter->has_hashmap();
|
||||
if (is_hash_enabled) {
|
||||
ObDatum out;
|
||||
if (OB_FAIL(iter->get_curr_probe_row())) {
|
||||
LOG_WARN("failed to get probe row", K(ret));
|
||||
} else if (OB_FAIL(iter->get_refactored(out))) {
|
||||
if (OB_HASH_NOT_EXIST != ret) {
|
||||
LOG_WARN("failed to find in hash map", K(ret));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
found_in_hash_map = true;
|
||||
if (OB_FAIL(expr.deep_copy_datum(ctx, out))) {
|
||||
LOG_WARN("failed to deep copy datum", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) || found_in_hash_map) {
|
||||
} else if (OB_FAIL(iter->get_next_row())) {
|
||||
if (OB_LIKELY(OB_ITER_END == ret)) {
|
||||
ret = OB_SUCCESS;
|
||||
iter_end = true;
|
||||
expr_datum.set_null();
|
||||
} else {
|
||||
LOG_WARN("get next row from subquery failed", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(iter->get_output().at(0)->eval(ctx, datum))) {
|
||||
} else if (OB_FAIL(iter->get_output().at(0)->eval(iter->get_eval_ctx(), datum))) {
|
||||
LOG_WARN("expr evaluate failed", K(ret));
|
||||
// deep copy datum since the following iter->get_next_row() make datum invalid.
|
||||
} else if (OB_FAIL(expr.deep_copy_datum(ctx, *datum))) {
|
||||
LOG_WARN("deep copy datum failed", K(ret), K(datum));
|
||||
} else {
|
||||
}
|
||||
if (OB_SUCC(ret) && is_hash_enabled
|
||||
&& iter->probe_row_.cnt_ > 0
|
||||
&& !found_in_hash_map
|
||||
&& !iter_end) {
|
||||
//now we can insert curr row and curr result into hashmap
|
||||
//first to get arena allocator from sp_iter to deep copy row
|
||||
ObDatum value;
|
||||
DatumRow row_key;
|
||||
row_key.cnt_ = iter->probe_row_.cnt_;
|
||||
//first check memory is enough
|
||||
int64_t need_size = datum->len_ + sizeof(ObDatum);
|
||||
for (int64_t i = 0; i < iter->probe_row_.cnt_; ++i) {
|
||||
need_size += (iter->probe_row_.elems_[i].len_ + sizeof(ObDatum));
|
||||
}
|
||||
bool can_insert = iter->check_can_insert(need_size);
|
||||
ObIAllocator *alloc = nullptr;
|
||||
if (!can_insert) {
|
||||
//memory is exceed, do not insert new rows
|
||||
} else if (OB_FAIL(iter->get_arena_allocator(alloc)) || OB_ISNULL(alloc)) {
|
||||
LOG_WARN("failed to get arena allocator", K(ret));
|
||||
} else if (OB_ISNULL(row_key.elems_
|
||||
= static_cast<ObDatum *> (alloc->alloc(sizeof(ObDatum) * row_key.cnt_)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc memory for row key", K(ret), K(row_key.cnt_));
|
||||
} else if (OB_FAIL(value.deep_copy(*datum, *alloc))) {
|
||||
LOG_WARN("deep copy datum failed", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < row_key.cnt_; ++i) {
|
||||
if (OB_FAIL(row_key.elems_[i].deep_copy(iter->probe_row_.elems_[i], *alloc))) {
|
||||
LOG_WARN("failed to copy probe row", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(iter->set_refactored(row_key, value, need_size))) {
|
||||
LOG_WARN("failed to insert into hashmap", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !found_in_hash_map && !iter_end) {
|
||||
if (OB_UNLIKELY(OB_SUCCESS == (ret = iter->get_next_row()))) {
|
||||
ret = OB_SUBQUERY_TOO_MANY_ROW;
|
||||
LOG_WARN("subquery too many rows", K(ret));
|
||||
@ -202,32 +412,59 @@ int ObExprSubQueryRef::expr_eval(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& ex
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::get_subquery_iter(ObEvalCtx& ctx, const ExtraInfo& extra_info, ObSubQueryIterator*& iter)
|
||||
int ObExprSubQueryRef::get_subquery_iter(ObEvalCtx &ctx,
|
||||
const Extra &extra,
|
||||
ObSubQueryIterator *&iter)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!extra_info.is_valid()) {
|
||||
if (!extra.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid extra info", K(ret), K(extra_info));
|
||||
LOG_WARN("invalid extra info", K(ret), K(extra));
|
||||
} else {
|
||||
ObOperatorKit* kit = ctx.exec_ctx_.get_operator_kit(extra_info.op_id_);
|
||||
ObOperatorKit *kit = ctx.exec_ctx_.get_operator_kit(extra.op_id_);
|
||||
if (OB_ISNULL(kit) || OB_ISNULL(kit->op_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("operator is NULL", K(ret), K(extra_info), KP(kit));
|
||||
LOG_WARN("operator is NULL", K(ret), K(extra), KP(kit));
|
||||
} else if (PHY_SUBPLAN_FILTER != kit->op_->get_spec().type_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("is not subplan filter operator", K(ret), K(extra_info), "spec", kit->op_->get_spec());
|
||||
LOG_WARN("is not subplan filter operator", K(ret), K(extra),
|
||||
"spec", kit->op_->get_spec());
|
||||
} else {
|
||||
ObSubPlanFilterOp* op = static_cast<ObSubPlanFilterOp*>(kit->op_);
|
||||
if (extra_info.iter_idx_ >= op->get_subplan_iters().count()) {
|
||||
ObSubPlanFilterOp *op = static_cast<ObSubPlanFilterOp *>(kit->op_);
|
||||
if (extra.iter_idx_ >= op->get_subplan_iters().count()) {
|
||||
ret = OB_ARRAY_OUT_OF_RANGE;
|
||||
LOG_WARN("out of range", K(ret), K(extra_info), "iter_cnt", op->get_subplan_iters().count());
|
||||
LOG_WARN("out of range", K(ret), K(extra),
|
||||
"iter_cnt", op->get_subplan_iters().count());
|
||||
} else {
|
||||
iter = op->get_subplan_iters().at(extra_info.iter_idx_);
|
||||
iter = op->get_subplan_iters().at(extra.iter_idx_);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprSubQueryRef::reset_onetime_expr(const ObExpr &expr, ObEvalCtx &ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const Extra &extra = Extra::get_info(expr);
|
||||
const ExtraInfo *extra_info = static_cast<ExtraInfo *>(expr.extra_info_);
|
||||
ObSubQueryIterator *iter = NULL;
|
||||
bool reset_for_onetime_expr = true;
|
||||
if (OB_ISNULL(extra_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("extra info is null", K(ret));
|
||||
} else if (OB_FAIL(get_subquery_iter(ctx, extra, iter))) {
|
||||
LOG_WARN("get sub query iterator failed", K(ret), K(extra));
|
||||
} else if (OB_ISNULL(iter)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("null iter returned", K(ret));
|
||||
} else if (!iter->is_onetime_plan()) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(iter->rewind(reset_for_onetime_expr))) {
|
||||
LOG_WARN("filter to rewind subquery iterator", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
Reference in New Issue
Block a user