提交 78662489 编写于 作者: O obdev 提交者: ob-robot

[to #47144085] fix pkg/subprogram cursor with default parameter

上级 eeffabef
......@@ -52,7 +52,9 @@ bool ObPackageStateVersion::operator ==(const ObPackageStateVersion &other)
{
bool b_ret = true;
if (package_version_ != other.package_version_
|| package_body_version_ != other.package_body_version_) {
|| (package_body_version_ != OB_INVALID_VERSION
&& other.package_body_version_ != OB_INVALID_VERSION
&& package_body_version_ != other.package_body_version_)) {
b_ret = false;
}
return b_ret;
......@@ -179,6 +181,7 @@ void ObPLPackageState::reset(ObSQLSessionInfo *session_info)
types_.reset();
vars_.reset();
inner_allocator_.reset();
cursor_allocator_.reset();
}
int ObPLPackageState::set_package_var_val(const int64_t var_idx, const ObObj &value)
......@@ -197,6 +200,10 @@ int ObPLPackageState::set_package_var_val(const int64_t var_idx, const ObObj &va
LOG_WARN("failed to alloc memory for pacakge var", K(ret), K(buf));
}
OZ (vars_.at(var_idx).deep_copy(value, buf, value.get_deep_copy_size(), pos));
} else if (value.is_pl_extend()) {
ObObj copy;
OZ (ObUserDefinedType::deep_copy_obj(inner_allocator_, value, copy));
OX (vars_.at(var_idx) = copy);
} else {
vars_.at(var_idx) = value;
}
......
......@@ -5995,7 +5995,7 @@ int ObPLResolver::resolve_cparams(ObIArray<ObRawExpr*> &exprs,
ObConstRawExpr *default_expr = NULL;
OZ (ObRawExprUtils::build_const_int_expr(expr_factory_, ObIntType, 0, default_expr));
CK (OB_NOT_NULL(default_expr));
OZ(default_expr->add_flag(IS_PL_MOCK_DEFAULT_EXPR));
OZ (default_expr->add_flag(IS_PL_MOCK_DEFAULT_EXPR));
OZ (func.add_expr(default_expr));
OZ (resolve_cparam_without_assign(default_expr, i, func, params, expr_idx));
}
......@@ -6005,9 +6005,14 @@ int ObPLResolver::resolve_cparams(ObIArray<ObRawExpr*> &exprs,
int64_t default_idx = static_cast<ObPLVar *>(formal_param)->get_default();
if (OB_UNLIKELY(-1 == default_idx)) {
ret = OB_ERR_SP_WRONG_ARG_NUM;
LOG_WARN("actual param expr is null", K(formal_param), K(ret));
LOG_WARN("actual param expr is null", KPC(formal_param), KPC(static_cast<ObPLVar *>(formal_param)), K(ret));
} else {
OX (expr_idx.at(i) = default_idx);
ObConstRawExpr *default_expr = NULL;
OZ (ObRawExprUtils::build_const_int_expr(expr_factory_, ObIntType, default_idx, default_expr));
CK (OB_NOT_NULL(default_expr));
OZ (default_expr->add_flag(IS_PL_MOCK_DEFAULT_EXPR));
OZ (func.add_expr(default_expr));
OZ (resolve_cparam_without_assign(default_expr, i, func, params, expr_idx));
}
} else {
ret = OB_ERR_UNEXPECTED;
......@@ -6795,8 +6800,10 @@ int ObPLResolver::resolve_cursor_actual_params(
OZ (iparams.push_back(const_cast<ObPLVar*>(var)));
} else if (cursor->get_routine_id() != stmt->get_namespace()->get_routine_id()) {
// not package cursor, not local cursor, must be subprogram cursor.
OZ (stmt->get_namespace()->get_cursor_var(
cursor->get_package_id(), cursor->get_routine_id(), cursor->get_index(), var));
OZ (stmt->get_namespace()->get_subprogram_var(cursor->get_package_id(),
cursor->get_routine_id(),
params_list.at(i),
var));
CK (OB_NOT_NULL(var));
OZ (iparams.push_back(const_cast<ObPLVar*>(var)));
} else {
......
......@@ -130,18 +130,18 @@ int ObExprGetPackageVar::eval_get_package_var(const ObExpr &expr,
} else if (package_id->is_null()
|| var_idx->is_null()
|| result_type->is_null()
|| spec_version->is_null()
|| body_version->is_null()) {
|| spec_version->is_null()) {
res.set_null();
} else {
ObObj res_obj;
OZ(calc(res_obj,
package_id->get_uint(),
spec_version->get_int(),
body_version->get_int(),
body_version->is_null() ? OB_INVALID_VERSION : body_version->get_int(),
var_idx->get_int(),
&ctx.exec_ctx_,
ctx.exec_ctx_.get_my_session()));
ctx.exec_ctx_.get_my_session()),
KPC(package_id), KPC(spec_version), KPC(body_version), KPC(var_idx));
if (OB_SUCC(ret)) {
if (ob_is_string_tc(res_obj.get_type())) {
ObString res_str;
......
......@@ -868,6 +868,41 @@ int ObSPIService::spi_calc_expr(ObPLExecCtx *ctx,
return ret;
}
int ObSPIService::spi_calc_subprogram_expr(ObPLExecCtx *ctx,
uint64_t package_id,
uint64_t routine_id,
int64_t expr_idx,
ObObjParam *result)
{
int ret = OB_SUCCESS;
ObExecContext *exec_ctx = NULL;
ObSQLSessionInfo *session_info = NULL;
ObPLExecState *state = NULL;
ObSqlExpression *expr = NULL;
CK (OB_NOT_NULL(exec_ctx = ctx->exec_ctx_));
CK (OB_NOT_NULL(session_info = exec_ctx->get_my_session()));
OZ (ObPLContext::get_exec_state_from_local(*session_info, package_id, routine_id, state));
CK (OB_NOT_NULL(state));
CK (OB_NOT_NULL(exec_ctx = state->get_exec_ctx().exec_ctx_));
CK (OB_NOT_NULL(expr = state->get_function().get_default_expr(expr_idx)));
if (OB_SUCC(ret)) {
ExecCtxBak exec_ctx_bak;
OX (exec_ctx_bak.backup(*exec_ctx));
OX (exec_ctx->set_physical_plan_ctx(&(state->get_physical_plan_ctx())));
if (OB_SUCC(ret) && state->get_function().get_expr_op_size() > 0) {
OZ (exec_ctx->init_expr_op(state->get_function().get_expr_op_size()));
}
OZ (state->get_function().get_frame_info().pre_alloc_exec_memory(*exec_ctx));
OZ (spi_calc_expr(&(state->get_exec_ctx()), expr, OB_INVALID_ID, result), KPC(expr));
if (state->get_function().get_expr_op_size() > 0) {
exec_ctx->reset_expr_op();
exec_ctx->get_allocator().free(exec_ctx->get_expr_op_ctx_store());
}
exec_ctx_bak.restore(*exec_ctx);
}
return ret;
}
int ObSPIService::spi_calc_package_expr(ObPLExecCtx *ctx,
uint64_t package_id,
int64_t expr_idx,
......@@ -3040,6 +3075,68 @@ int ObSPIService::dbms_dynamic_open(ObPLExecCtx *pl_ctx,
return ret;
}
int ObSPIService::prepare_cursor_parameters(ObPLExecCtx *ctx,
ObSQLSessionInfo &session_info,
uint64_t package_id,
uint64_t routine_id,
ObCusorDeclareLoc loc,
const int64_t *formal_param_idxs,
const ObSqlExpression **actual_param_exprs,
int64_t cursor_param_count)
{
int ret = OB_SUCCESS;
ObObjParam dummy_result;
for (int64_t i = 0; OB_SUCC(ret) && i < cursor_param_count; ++i) {
CK (OB_NOT_NULL(actual_param_exprs[i]));
OX (dummy_result.reset());
OX (dummy_result.ObObj::reset());
OZ (spi_calc_expr(ctx, actual_param_exprs[i], OB_INVALID_INDEX, &dummy_result),
K(i), K(cursor_param_count), KPC(actual_param_exprs[i]), K(dummy_result));
if (OB_SUCC(ret) && dummy_result.is_pl_mock_default_param()) {
ObSqlExpression *actual_param_expr = NULL;
if (DECL_PKG == loc) {
OZ (spi_calc_package_expr(ctx, package_id, dummy_result.get_int(), &dummy_result));
} else {
OZ (spi_calc_subprogram_expr(ctx, package_id, routine_id, dummy_result.get_int(), &dummy_result));
}
}
if (OB_FAIL(ret)) {
} else if (DECL_PKG == loc) {
OZ (spi_set_package_variable(ctx, package_id, formal_param_idxs[i], dummy_result));
} else if (DECL_SUBPROG == loc) {
OZ (ObPLContext::set_subprogram_var_from_local(
session_info, package_id, routine_id, formal_param_idxs[i], dummy_result));
} else {
int64_t result_idx = formal_param_idxs[i];
CK (DECL_LOCAL == loc);
CK (result_idx >= 0 && result_idx < ctx->params_->count());
if (OB_SUCC(ret)) {
ObObjParam &param = ctx->params_->at(result_idx);
bool is_ref_cursor = param.is_ref_cursor_type();
if (!dummy_result.is_ext()) {
dummy_result.ObObj::set_scale(param.get_meta().get_scale());
dummy_result.set_accuracy(ctx->params_->at(result_idx).get_accuracy());
param = dummy_result;
param.set_is_ref_cursor_type(is_ref_cursor);
param.set_param_meta();
} else if (!is_ref_cursor) {
int64_t orig_udt_id = ctx->params_->at(result_idx).get_udt_id();
ctx->params_->at(result_idx) = dummy_result;
ctx->params_->at(result_idx).set_udt_id(orig_udt_id);
ctx->params_->at(result_idx).set_param_meta();
}
}
}
}
return ret;
}
int ObSPIService::spi_cursor_open(ObPLExecCtx *ctx,
const char *sql,
const char *ps_sql,
......@@ -3070,13 +3167,8 @@ int ObSPIService::spi_cursor_open(ObPLExecCtx *ctx,
LOG_WARN("Argument passed in is NULL", K(ctx), K(sql), K(ps_sql), K(type), K(sql_param_exprs), K(sql_param_count), K(ret));
} else if (OB_FAIL(spi_get_cursor_info(ctx, package_id, routine_id, cursor_index, cursor, cursor_var, loc))) {
LOG_WARN("failed to get cursor info", K(ret), K(cursor_index));
// } else if (OB_ISNULL(cursor)) {
// } else if (!cursor_var.is_ext()) {
// ret = OB_INVALID_ARGUMENT;
// LOG_WARN("cursor var in is null", K(ret));
} else if (OB_FAIL(cursor_open_check(ctx, package_id, routine_id,
cursor_index, cursor, cursor_var, loc))) {
// ret = OB_INVALID_ARGUMENT;
LOG_WARN("cursor info not init", K(ret), K(cursor));
} else if (cursor->isopen()) {
ret = OB_ER_SP_CURSOR_ALREADY_OPEN;
......@@ -3100,29 +3192,9 @@ int ObSPIService::spi_cursor_open(ObPLExecCtx *ctx,
LOG_WARN("cursor params in not valid",
K(cursor_param_count), K(formal_param_idxs), K(actual_param_exprs), K(ret));
} else {
ObObjParam dummy_result;
for (int64_t i = 0; OB_SUCC(ret) && i < cursor_param_count; ++i) {
CK (OB_NOT_NULL(actual_param_exprs[i]));
OX (dummy_result.reset());
OX (dummy_result.ObObj::reset());
OZ (spi_calc_expr(
ctx,
actual_param_exprs[i],
DECL_LOCAL == loc ? formal_param_idxs[i] : OB_INVALID_INDEX,
&dummy_result),
i, cursor_param_count, *actual_param_exprs[i], dummy_result);
if (OB_SUCC(ret)) {
if (DECL_PKG == loc) {
OZ (spi_set_package_variable(ctx, package_id, formal_param_idxs[i], dummy_result));
} else if (DECL_SUBPROG == loc) {
OZ (ObPLContext::set_subprogram_var_from_local(*session_info,
package_id,
routine_id,
formal_param_idxs[i],
dummy_result));
} else { /* do nothing */ }
}
}
OZ (prepare_cursor_parameters(
ctx, *session_info, package_id,
routine_id, loc, formal_param_idxs, actual_param_exprs, cursor_param_count));
}
if (OB_SUCC(ret) && DECL_SUBPROG == loc) {
......
......@@ -319,6 +319,13 @@ public:
const ObSqlExpression *expr,
const int64_t result_idx,
ObObjParam *result);
static int spi_calc_subprogram_expr(pl::ObPLExecCtx *ctx,
uint64_t package_id,
uint64_t routine_id,
int64_t expr_idx,
ObObjParam *result);
static int spi_calc_package_expr(pl::ObPLExecCtx *ctx,
uint64_t package_id,
int64_t expr_idx,
......@@ -945,6 +952,15 @@ private:
const ObSqlExpression &expr,
ObIArray<ObObj> &src_array,
ObIArray<ObObj> &dst_array);
static int prepare_cursor_parameters(pl::ObPLExecCtx *ctx,
ObSQLSessionInfo &session_info,
uint64_t package_id,
uint64_t routine_id,
ObCusorDeclareLoc loc,
const int64_t *formal_param_idxs,
const ObSqlExpression **actual_param_exprs,
int64_t cursor_param_count);
};
}
......
......@@ -99,7 +99,7 @@ int ObCallProcedureResolver::resolve_cparams(const ParseNode *params_node,
OZ (ObRawExprUtils::build_const_int_expr(
*(params_.expr_factory_), ObIntType, 0, default_expr));
CK (OB_NOT_NULL(default_expr));
OZ(default_expr->add_flag(IS_PL_MOCK_DEFAULT_EXPR));
OZ (default_expr->add_flag(IS_PL_MOCK_DEFAULT_EXPR));
OX (params.at(i) = default_expr);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册