[to #49602206] no codegen objaccess & can calc it in pure sql context

This commit is contained in:
obdev
2023-05-23 05:11:45 +00:00
committed by ob-robot
parent a14c578253
commit 54fbf31d94
7 changed files with 285 additions and 85 deletions

View File

@ -16,6 +16,7 @@
#include "sql/engine/ob_exec_context.h"
#include "sql/ob_spi.h"
#include "pl/ob_pl.h"
#include "pl/ob_pl_resolver.h"
#include "sql/engine/expr/ob_expr_lob_utils.h"
namespace oceanbase
@ -32,7 +33,8 @@ ObExprObjAccess::ExtraInfo::ExtraInfo(common::ObIAllocator &alloc, ObExprOperato
for_write_(false),
property_type_(pl::ObCollectionType::INVALID_PROPERTY),
coll_idx_(OB_INVALID_INDEX),
extend_size_(0)
extend_size_(0),
access_idxs_(alloc)
{
}
@ -74,6 +76,7 @@ void ObExprObjAccess::ExtraInfo::reset()
property_type_ = pl::ObCollectionType::INVALID_PROPERTY;
coll_idx_ = OB_INVALID_INDEX;
extend_size_ = 0;
access_idxs_.reset();
}
void ObExprObjAccess::reset()
@ -105,6 +108,7 @@ int ObExprObjAccess::ExtraInfo::assign(const ObExprObjAccess::ExtraInfo &other)
coll_idx_ = other.coll_idx_;
extend_size_ = other.extend_size_;
OZ(param_idxs_.assign(other.param_idxs_));
OZ(access_idxs_.assign(other.access_idxs_));
return ret;
}
@ -211,26 +215,169 @@ int ObExprObjAccess::calc_result(ObObj &result,
get_result_type().get_extend_size(),
param_store,
objs_stack,
param_num);
param_num,
nullptr);
}
int ObExprObjAccess::ExtraInfo::get_collection_attr(int64_t* params,
const pl::ObObjAccessIdx &current_access,
bool for_write,
void *&current_value) const
{
int ret = OB_SUCCESS;
pl::ObPLCollection *current_coll = reinterpret_cast<pl::ObPLCollection*>(current_value);
int64_t element_idx;
CK (OB_NOT_NULL(current_coll));
if (OB_SUCC(ret) && !current_coll->is_inited()) {
ret = OB_NOT_INIT;
LOG_WARN("", K(ret), KPC(current_coll));
}
if (OB_SUCC(ret) && !current_access.is_property()) {
if (current_access.is_const()) {
element_idx = current_access.var_index_ - 1;
} else {
element_idx = params[current_access.var_index_] - 1;
}
if (element_idx < 0 || element_idx >= current_coll->get_count()) {
ret = OB_READ_NOTHING;
LOG_WARN("", K(ret), K(element_idx));
}
}
if (OB_SUCC(ret) && !current_access.is_property()) {
ObObj &element_obj = current_coll->get_data()[element_idx];
if (ObMaxType == element_obj.get_type()) {
if (!for_write) {
ret = OB_READ_NOTHING;
LOG_WARN("", K(ret), KPC(current_coll));
} else {
if (current_access.var_type_.is_composite_type()) {
element_obj.set_type(ObExtendType);
}
}
}
OX (current_value = &element_obj);
}
return ret;
}
int ObExprObjAccess::ExtraInfo::get_record_attr(const pl::ObObjAccessIdx &current_access,
uint64_t udt_id,
bool for_write,
void *&current_value,
ObEvalCtx &ctx) const
{
int ret = OB_SUCCESS;
ObArenaAllocator alloc;
const pl::ObUserDefinedType *user_type = NULL;
const pl::ObRecordType *record_type = NULL;
pl::ObPLComposite *current_composite = reinterpret_cast<pl::ObPLComposite*>(current_value);
pl::ObPLRecord* current_record = static_cast<pl::ObPLRecord*>(current_composite);
ObObj* element_obj = NULL;
CK (OB_NOT_NULL(current_composite));
CK (current_composite->is_record());
CK (OB_NOT_NULL(current_record));
CK (OB_NOT_NULL(ctx.exec_ctx_.get_my_session()));
CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_ctx()));
CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_ctx()->schema_guard_));
CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_proxy()));
if (OB_FAIL(ret)) {
} else if (ctx.exec_ctx_.get_my_session()->get_pl_context()) {
pl::ObPLINS *ns = ctx.exec_ctx_.get_my_session()->get_pl_context()->get_current_ctx();
CK (OB_NOT_NULL(ns));
OZ (ns->get_user_type(udt_id, user_type));
} else {
pl::ObPLResolveCtx resolve_ctx(alloc,
*ctx.exec_ctx_.get_my_session(),
*ctx.exec_ctx_.get_sql_ctx()->schema_guard_,
*ctx.exec_ctx_.get_package_guard(),
*ctx.exec_ctx_.get_sql_proxy(),
false);
OZ (resolve_ctx.get_user_type(udt_id, user_type));
}
CK (OB_NOT_NULL(user_type));
CK (user_type->is_record_type());
CK (OB_NOT_NULL(record_type = static_cast<const pl::ObRecordType*>(user_type)));
CK (current_access.is_const());
if (OB_SUCC(ret) && user_type->is_object_type() && for_write_ && current_composite->is_null()) {
ret = OB_ERR_ACCESS_INTO_NULL;
LOG_WARN("", K(ret), KPC(current_composite));
}
OZ (current_record->get_element(current_access.var_index_, element_obj));
CK (OB_NOT_NULL(current_value = element_obj));
return ret;
}
int ObExprObjAccess::ExtraInfo::get_attr_func(int64_t param_cnt,
int64_t *params,
int64_t *element_val,
ObEvalCtx &ctx) const
{
int ret = OB_SUCCESS;
pl::ObPLComposite *composite_addr
= reinterpret_cast<pl::ObPLComposite*>(params[access_idxs_.at(0).var_index_]);
void *current_value = NULL;
CK (OB_NOT_NULL(element_val));
CK (access_idxs_.count() > 0);
for (int64_t i = 1; OB_SUCC(ret) && i < access_idxs_.count(); ++i) {
const pl::ObPLDataType &parent_type = access_idxs_.at(i - 1).var_type_;
const pl::ObObjAccessIdx &parent_access = access_idxs_.at(i - 1);
const pl::ObObjAccessIdx &current_access = access_idxs_.at(i);
current_value = composite_addr;
if (parent_type.is_collection_type()) {
OZ (get_collection_attr(params,
current_access,
for_write_,
current_value));
} else {
OZ (get_record_attr(current_access,
parent_type.get_user_type_id(),
for_write_,
current_value,
ctx));;
}
if (OB_FAIL(ret)) {
} else if (current_access.var_type_.is_composite_type()) {
ObObj* value = reinterpret_cast<ObObj*>(current_value);
CK (OB_NOT_NULL(value));
CK (value->is_ext());
OX (composite_addr = reinterpret_cast<pl::ObPLComposite*>(value->get_ext()));
CK (OB_NOT_NULL(composite_addr));
}
}
if (OB_FAIL(ret)) {
} else if (pl::ObObjAccessIdx::get_final_type(access_idxs_).is_obj_type()) {
*element_val = reinterpret_cast<int64_t>(current_value);
} else {
*element_val = reinterpret_cast<int64_t>(composite_addr);
}
return ret;
}
int ObExprObjAccess::ExtraInfo::calc(ObObj &result,
const ObObjMeta &res_type,
const int32_t extend_size,
const ParamStore &param_store,
const common::ObObj *params,
int64_t param_num) const
int64_t param_num,
ObEvalCtx *ctx) const
{
int ret = OB_SUCCESS;
typedef int32_t (*GetAttr)(int64_t, int64_t [], int64_t *);
GetAttr get_attr = reinterpret_cast<GetAttr>(get_attr_func_);
ParamArray param_array;
CK (OB_NOT_NULL(get_attr));
OZ (init_param_array(param_store, params, param_num, param_array));
if (OB_SUCC(ret)) {
int64_t *param_ptr = const_cast<int64_t *>(param_array.head());
int64_t attr_addr = 0;
OZ (get_attr(param_array.count(), param_ptr, &attr_addr));
if (OB_NOT_NULL(get_attr)) {
OZ (get_attr(param_array.count(), param_ptr, &attr_addr));
} else {
CK (OB_NOT_NULL(ctx));
OZ (get_attr_func(param_array.count(), param_ptr, &attr_addr, *ctx));
}
if (OB_FAIL(ret)) {
if (OB_NOT_INIT == ret && pl::ObCollectionType::EXISTS_PROPERTY == property_type_) {
ret = OB_SUCCESS;
@ -285,7 +432,6 @@ int ObExprObjAccess::ExtraInfo::calc(ObObj &result,
int ObExprObjAccess::ExtraInfo::from_raw_expr(const ObObjAccessRawExpr &raw_access)
{
int ret = 0;
CK(0 != raw_access.get_get_attr_func_addr());
if (OB_SUCC(ret)) {
extend_size_ = raw_access.get_result_type().get_extend_size();
get_attr_func_ = raw_access.get_get_attr_func_addr();
@ -298,6 +444,8 @@ int ObExprObjAccess::ExtraInfo::from_raw_expr(const ObObjAccessRawExpr &raw_acce
}
OZ(param_idxs_.init(raw_access.get_var_indexs().count()));
OZ(param_idxs_.assign(raw_access.get_var_indexs()));
OZ(access_idxs_.init(raw_access.get_access_idxs().count()));
OZ(access_idxs_.assign(raw_access.get_access_idxs()));
}
return ret;
}
@ -313,7 +461,6 @@ int ObExprObjAccess::cg_expr(ObExprCGCtx &op_cg_ctx,
LOG_WARN("allocate memory failed", K(ret));
} else {
const ObObjAccessRawExpr &raw_access = static_cast<const ObObjAccessRawExpr &>(raw_expr);
CK(0 != raw_access.get_get_attr_func_addr());
if (OB_SUCC(ret)) {
info->extend_size_ = raw_expr.get_result_type().get_extend_size();
info->get_attr_func_ = raw_access.get_get_attr_func_addr();
@ -327,6 +474,8 @@ int ObExprObjAccess::cg_expr(ObExprCGCtx &op_cg_ctx,
info->coll_idx_ = coll_idx;
OZ(info->param_idxs_.init(raw_access.get_var_indexs().count()));
OZ(info->param_idxs_.assign(raw_access.get_var_indexs()));
OZ(info->access_idxs_.init(raw_access.get_access_idxs().count()));
OZ(info->access_idxs_.assign(raw_access.get_access_idxs()));
}
if (OB_SUCC(ret)) {
rt_expr.extra_info_ = info;
@ -357,7 +506,8 @@ int ObExprObjAccess::eval_obj_access(const ObExpr &expr,
info->extend_size_,
param_store,
params,
expr.arg_cnt_));
expr.arg_cnt_,
&ctx));
OZ(expr_datum.from_obj(result, expr.obj_datum_map_));
if (is_lob_storage(result.get_type())) {

View File

@ -75,13 +75,28 @@ public:
int update_coll_first_last(
const ParamStore &param_store, const ObObj *objs_stack, int64_t param_num) const;
int get_attr_func(int64_t param_cnt,
int64_t* params,
int64_t *element_val,
ObEvalCtx &ctx) const;
int get_record_attr(const pl::ObObjAccessIdx &current_access,
uint64_t udt_id,
bool for_write,
void *&current_value,
ObEvalCtx &ctx) const;
int get_collection_attr(int64_t* params,
const pl::ObObjAccessIdx &current_access,
bool for_write,
void *&current_value) const;
int calc(ObObj &result,
const ObObjMeta &res_type,
const int32_t extend_size,
const ParamStore &param_store,
const common::ObObj *params,
int64_t param_num) const;
int64_t param_num,
ObEvalCtx *ctx) const;
TO_STRING_KV(K_(get_attr_func),
K_(param_idxs),
@ -99,6 +114,7 @@ public:
int64_t coll_idx_; // index of Collection in ParamArray
// extend size only used in static engine, the old expr get extend size from ObExprResType
int32_t extend_size_;
common::ObFixedArray<pl::ObObjAccessIdx, common::ObIAllocator> access_idxs_;
};
private:
ExtraInfo info_;