diff --git a/src/sql/engine/expr/ob_expr_extra_info_factory.cpp b/src/sql/engine/expr/ob_expr_extra_info_factory.cpp index 01ace0324b..3955f972df 100644 --- a/src/sql/engine/expr/ob_expr_extra_info_factory.cpp +++ b/src/sql/engine/expr/ob_expr_extra_info_factory.cpp @@ -30,6 +30,7 @@ #include "sql/engine/expr/ob_expr_plsql_variable.h" #include "sql/engine/expr/ob_pl_expr_subquery.h" #include "sql/engine/expr/ob_expr_cast.h" +#include "sql/engine/expr/ob_expr_lrpad.h" namespace oceanbase { @@ -98,6 +99,8 @@ void ObExprExtraInfoFactory::register_expr_extra_infos() REG_EXTRA_INFO(T_FUN_SYS_GREATEST, ObExprOperator::DatumCastExtraInfo); REG_EXTRA_INFO(T_FUN_SYS_NULLIF, ObExprOperator::DatumCastExtraInfo); REG_EXTRA_INFO(T_FUN_SYS_CAST, ObExprCast::CastMultisetExtraInfo); + REG_EXTRA_INFO(T_FUN_SYS_LPAD, ObExprOracleLRpadInfo); + REG_EXTRA_INFO(T_FUN_SYS_RPAD, ObExprOracleLRpadInfo); } } // end namespace sql diff --git a/src/sql/engine/expr/ob_expr_lrpad.cpp b/src/sql/engine/expr/ob_expr_lrpad.cpp index bd8d9f7076..c312bc80ca 100644 --- a/src/sql/engine/expr/ob_expr_lrpad.cpp +++ b/src/sql/engine/expr/ob_expr_lrpad.cpp @@ -1110,10 +1110,21 @@ int ObExprBaseLRpad::calc_oracle(LRpadType pad_type, const ObExpr &expr, int64_t text_width = 0; const ObString &str_text = text.get_string(); const ObString &str_pad = pad_text.get_string(); - int64_t max_result_size = ob_is_text_tc(expr.datum_meta_.type_) ? - OB_MAX_LONGTEXT_LENGTH: OB_MAX_ORACLE_VARCHAR_LENGTH; const ObCollationType cs_type = expr.datum_meta_.cs_type_; + // max varchar size is 4000 in Oracle SQL, however 32767 in PL/SQL + // OB does not support `MAX_STRING_SIZE = EXTENDED` for now + const ObExprOracleLRpadInfo *info = nullptr; + int64_t max_varchar_size = OB_MAX_ORACLE_VARCHAR_LENGTH; + if (OB_NOT_NULL(info = static_cast(expr.extra_info_)) && + info->is_called_in_sql_) { + const int64_t STANDARD_MAX_ORACLE_VARCHAR_LENGTH = 4000; + max_varchar_size = STANDARD_MAX_ORACLE_VARCHAR_LENGTH; + } + int64_t max_result_size = ob_is_text_tc(expr.datum_meta_.type_) + ? OB_MAX_LONGTEXT_LENGTH + : max_varchar_size; + number::ObNumber len_num(len.get_number()); int64_t decimal_parts = -1; if (len_num.is_negative()) { @@ -1301,9 +1312,25 @@ int ObExprOracleLpad::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_exp ObExpr &rt_expr) const { int ret = OB_SUCCESS; - UNUSED(expr_cg_ctx); UNUSED(raw_expr); - rt_expr.eval_func_ = calc_oracle_lpad_expr; + if (OB_ISNULL(expr_cg_ctx.allocator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Allocator is NULL", K(ret)); + } else { + ObIAllocator &alloc = *expr_cg_ctx.allocator_; + ObIExprExtraInfo *extra_info = nullptr; + if (OB_FAIL(ObExprExtraInfoFactory::alloc(alloc, rt_expr.type_, extra_info))) { + LOG_WARN("Failed to allocate memory for ObExprOracleLRpadInfo", K(ret)); + } else if (OB_ISNULL(extra_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extra_info should not be nullptr", K(ret)); + } else { + ObExprOracleLRpadInfo *info = static_cast(extra_info); + info->is_called_in_sql_ = is_called_in_sql(); + rt_expr.extra_info_ = extra_info; + rt_expr.eval_func_ = calc_oracle_lpad_expr; + } + } return ret; } @@ -1358,9 +1385,25 @@ int ObExprOracleRpad::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_exp ObExpr &rt_expr) const { int ret = OB_SUCCESS; - UNUSED(expr_cg_ctx); UNUSED(raw_expr); - rt_expr.eval_func_ = calc_oracle_rpad_expr; + if (OB_ISNULL(expr_cg_ctx.allocator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Allocator is NULL", K(ret)); + } else { + ObIAllocator &alloc = *expr_cg_ctx.allocator_; + ObIExprExtraInfo *extra_info = nullptr; + if (OB_FAIL(ObExprExtraInfoFactory::alloc(alloc, rt_expr.type_, extra_info))) { + LOG_WARN("Failed to allocate memory for ObExprOracleLRpadInfo", K(ret)); + } else if (OB_ISNULL(extra_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extra_info should not be nullptr", K(ret)); + } else { + ObExprOracleLRpadInfo *info = static_cast(extra_info); + info->is_called_in_sql_ = is_called_in_sql(); + rt_expr.extra_info_ = extra_info; + rt_expr.eval_func_ = calc_oracle_rpad_expr; + } + } return ret; } @@ -1371,5 +1414,43 @@ int ObExprOracleRpad::calc_oracle_rpad_expr(const ObExpr &expr, ObEvalCtx &ctx, } /* ObExprRpadOracle END }}} */ +OB_DEF_SERIALIZE(ObExprOracleLRpadInfo) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, is_called_in_sql_); + return ret; +} + +OB_DEF_DESERIALIZE(ObExprOracleLRpadInfo) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, is_called_in_sql_); + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObExprOracleLRpadInfo) +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, is_called_in_sql_); + return len; +} + +int ObExprOracleLRpadInfo::deep_copy(common::ObIAllocator &allocator, + const ObExprOperatorType type, + ObIExprExtraInfo *&copied_info) const +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObExprExtraInfoFactory::alloc(allocator, type, copied_info))) { + LOG_WARN("Failed to allocate memory for ObExprOracleLRpadInfo", K(ret)); + } else if (OB_ISNULL(copied_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extra_info should not be nullptr", K(ret)); + } else { + ObExprOracleLRpadInfo *other = static_cast(copied_info); + other->is_called_in_sql_ = is_called_in_sql_; + } + return ret; +} + } // namespace sql } // namespace oceanbase diff --git a/src/sql/engine/expr/ob_expr_lrpad.h b/src/sql/engine/expr/ob_expr_lrpad.h index 11ebe229e3..330600105d 100644 --- a/src/sql/engine/expr/ob_expr_lrpad.h +++ b/src/sql/engine/expr/ob_expr_lrpad.h @@ -14,6 +14,7 @@ #define OCEANBASE_SQL_ENGINE_EXPR_OB_SQL_EXPR_LRPAD_ #include "sql/engine/expr/ob_expr_operator.h" +#include "sql/engine/expr/ob_i_expr_extra_info.h" namespace oceanbase { @@ -224,6 +225,24 @@ private: DISALLOW_COPY_AND_ASSIGN(ObExprOracleRpad); }; +struct ObExprOracleLRpadInfo : public ObIExprExtraInfo +{ + OB_UNIS_VERSION(1); +public: + ObExprOracleLRpadInfo(common::ObIAllocator &alloc, ObExprOperatorType type) + : ObIExprExtraInfo(alloc, type), + is_called_in_sql_(true) + { + } + + virtual int deep_copy(common::ObIAllocator &allocator, + const ObExprOperatorType type, + ObIExprExtraInfo *&copied_info) const override; + +public: + bool is_called_in_sql_; +}; + } // namespace sql } // namespace oceanbase #endif // OCEANBASE_SQL_ENGINE_EXPR_OB_SQL_EXPR_RPAD_