From 534c25f11fd7bcd748a6c1fe3844353e47186251 Mon Sep 17 00:00:00 2001 From: obdev Date: Fri, 7 Apr 2023 08:11:21 +0000 Subject: [PATCH] [to #48896499] fix object construct with null parameter --- .../engine/expr/ob_expr_object_construct.cpp | 43 ++++++++++++++++++- .../engine/expr/ob_expr_object_construct.h | 2 + 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/sql/engine/expr/ob_expr_object_construct.cpp b/src/sql/engine/expr/ob_expr_object_construct.cpp index d3c284ebc0..6850c61f46 100644 --- a/src/sql/engine/expr/ob_expr_object_construct.cpp +++ b/src/sql/engine/expr/ob_expr_object_construct.cpp @@ -20,6 +20,7 @@ #include "pl/ob_pl.h" #include "pl/ob_pl_user_type.h" #include "sql/ob_spi.h" +#include "pl/ob_pl_resolver.h" namespace oceanbase { @@ -93,6 +94,42 @@ int ObExprObjectConstruct::cg_expr(ObExprCGCtx &op_cg_ctx, return ret; } +int ObExprObjectConstruct::newx(ObEvalCtx &ctx, ObObj &result, uint64_t udt_id) +{ + int ret = OB_SUCCESS; + auto session = ctx.exec_ctx_.get_my_session(); + auto &exec_ctx = ctx.exec_ctx_; + ObIAllocator &alloc = ctx.exec_ctx_.get_allocator(); + pl::ObPLPackageGuard package_guard(session->get_effective_tenant_id()); + pl::ObPLResolveCtx resolve_ctx(alloc, + *session, + *(exec_ctx.get_sql_ctx()->schema_guard_), + package_guard, + *(exec_ctx.get_sql_proxy()), + false); + pl::ObPLINS *ns = NULL; + if (NULL == session->get_pl_context()) { + OZ (package_guard.init()); + OX (ns = &resolve_ctx); + } else { + ns = session->get_pl_context()->get_current_ctx(); + } + if (OB_SUCC(ret)) { + ObObj new_composite; + int64_t ptr = 0; + int64_t init_size = OB_INVALID_SIZE; + ObArenaAllocator tmp_alloc; + const pl::ObUserDefinedType *user_type = NULL; + OZ (ns->get_user_type(udt_id, user_type, &tmp_alloc)); + CK (OB_NOT_NULL(user_type)); + OZ (user_type->newx(alloc, ns, ptr)); + OZ (user_type->get_size(*ns, pl::PL_TYPE_INIT_SIZE, init_size)); + OX (new_composite.set_extend(ptr, user_type->get_type(), init_size)); + OX (result = new_composite); + } + return ret; +} + int ObExprObjectConstruct::eval_object_construct(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res) { int ret = OB_SUCCESS; @@ -128,7 +165,11 @@ int ObExprObjectConstruct::eval_object_construct(const ObExpr &expr, ObEvalCtx & } else { new(record)pl::ObPLRecord(info->udt_id_, expr.arg_cnt_); for (int64_t i = 0; i < expr.arg_cnt_; ++i) { - record->get_element()[i] = objs[i]; + if (objs[i].is_null() && info->elem_types_.at(i).is_ext()) { + OZ (newx(ctx, record->get_element()[i], info->elem_types_.at(i).get_udt_id())); + } else { + OX (record->get_element()[i] = objs[i]); + } if (OB_SUCC(ret) && (ObCharType == info->elem_types_.at(i).get_type() || ObNCharType == info->elem_types_.at(i).get_type())) { OZ (ObSPIService::spi_pad_char_or_varchar(session, diff --git a/src/sql/engine/expr/ob_expr_object_construct.h b/src/sql/engine/expr/ob_expr_object_construct.h index 07dc87b80b..5373d50435 100644 --- a/src/sql/engine/expr/ob_expr_object_construct.h +++ b/src/sql/engine/expr/ob_expr_object_construct.h @@ -68,6 +68,8 @@ public: int64_t param_num); static int fill_obj_stack(const ObExpr &expr, ObEvalCtx &ctx, ObObj *objs); + static int newx(ObEvalCtx &ctx, ObObj &result, uint64_t udt_id); + virtual void reset() { rowsize_ = 0; udt_id_ = OB_INVALID_ID;