diff --git a/src/share/object/ob_obj_cast.cpp b/src/share/object/ob_obj_cast.cpp index 28b46f6971..02b74c0d3f 100644 --- a/src/share/object/ob_obj_cast.cpp +++ b/src/share/object/ob_obj_cast.cpp @@ -34,6 +34,8 @@ #include "lib/geo/ob_geometry_cast.h" #include "sql/engine/expr/ob_datum_cast.h" #include "sql/engine/expr/ob_expr_util.h" +#include "src/storage/lob/ob_lob_manager.h" +#include "sql/engine/expr/ob_expr_json_func_helper.h" #ifdef OB_BUILD_ORACLE_XML #include "lib/xml/ob_xml_util.h" #include "lib/xml/ob_xml_parser.h" @@ -14350,7 +14352,7 @@ int ObObjCaster::to_type(const ObExpectType &expect_type, return ret; } -const char OB_JSON_NULL[2] = {'\0', '\0'}; // binary json null +const ObJsonZeroVal OB_JSON_ZERO = ObJsonZeroVal(); // binary json null int ObObjCaster::get_zero_value(const ObObjType expect_type, ObCollationType expect_cs_type, ObObj &zero_obj) { @@ -14358,10 +14360,15 @@ int ObObjCaster::get_zero_value(const ObObjType expect_type, ObCollationType exp ObObjCastParams params; //构造一个空的cast_param对象,适配SET_RES_XXX宏定义 ObCastMode cast_mode = CM_WARN_ON_FAIL; params.warning_ = 1; //将warning code设置为1,避免SET_RES_XXX宏将其当做真实的warning处理 - if (ob_is_string_tc(expect_type) || ob_is_text_tc(expect_type)) { + if (ob_is_string_tc(expect_type)) { zero_obj.set_string(expect_type, ""); } else if (ob_is_text_tc(expect_type)) { - zero_obj.set_lob_value(expect_type, static_cast(NULL), 0); + if (ob_is_large_text(expect_type)) { + zero_obj.set_lob_value(expect_type, reinterpret_cast(&ObLobManager::ZERO_LOB), sizeof(ObLobCommon)); + zero_obj.set_has_lob_header(); + } else { // tinytext + zero_obj.set_string(expect_type, ""); + } } else if (ob_is_int_tc(expect_type)) { int64_t value = 0; SET_RES_INT(zero_obj); @@ -14412,7 +14419,8 @@ int ObObjCaster::get_zero_value(const ObObjType expect_type, ObCollationType exp ret = OB_NOT_SUPPORTED; LOG_WARN("urowid with default value not supported"); } else if (expect_type == ObJsonType) { - zero_obj.set_json_value(expect_type, OB_JSON_NULL, 2); + zero_obj.set_json_value(expect_type, reinterpret_cast(&OB_JSON_ZERO), ObJsonZeroVal::OB_JSON_ZERO_VAL_LENGTH); + zero_obj.set_has_lob_header(); } else if (expect_type == ObDecimalIntType) { zero_obj.set_decimal_int(0, 0, nullptr); } else if (ob_is_user_defined_sql_type(expect_type)) { diff --git a/src/sql/engine/dml/ob_dml_service.cpp b/src/sql/engine/dml/ob_dml_service.cpp index 631c09a10f..5b1c84d82b 100644 --- a/src/sql/engine/dml/ob_dml_service.cpp +++ b/src/sql/engine/dml/ob_dml_service.cpp @@ -119,15 +119,11 @@ int ObDMLService::check_row_null(const ObExprPtrIArray &row, res_alloc, zero_obj))) { LOG_WARN("padding fixed string value failed", K(ret)); - } else if (OB_FAIL(ObTextStringResult::ob_convert_obj_temporay_lob(zero_obj, eval_ctx.exec_ctx_.get_allocator()))) { - LOG_WARN("convert lob types zero obj failed", K(ret), K(zero_obj)); - } else if (OB_FAIL(!is_decimal_int && row_datum.from_obj(zero_obj))) { + } else if (!is_decimal_int && OB_FAIL(row_datum.from_obj(zero_obj))) { LOG_WARN("assign zero obj to datum failed", K(ret), K(zero_obj)); - } else if (is_lob_storage(zero_obj.get_type()) && - OB_FAIL(ob_adjust_lob_datum(zero_obj, row.at(col_idx)->obj_meta_, - eval_ctx.exec_ctx_.get_allocator(), - row_datum))) { - LOG_WARN("adjust lob datum failed", K(ret), K(i), K(col_idx), + } else if (zero_obj.is_lob_storage() && zero_obj.has_lob_header() != row.at(col_idx)->obj_meta_.has_lob_header()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has lob header mark is wrong", K(ret), K(i), K(col_idx), K(zero_obj.get_meta()), K(row.at(col_idx)->obj_meta_)); } else { //output warning msg diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.h b/src/sql/engine/expr/ob_expr_json_func_helper.h index a72a04e7a3..ceb6e7d015 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.h +++ b/src/sql/engine/expr/ob_expr_json_func_helper.h @@ -251,6 +251,17 @@ private: DISALLOW_COPY_AND_ASSIGN(ObJsonExprHelper); }; +struct ObJsonZeroVal +{ + static const int32_t OB_JSON_ZERO_VAL_LENGTH = sizeof(ObLobCommon) + 2; + ObJsonZeroVal() : header_(), json_bin_() { + json_bin_[0] = '\0'; + json_bin_[1] = '\0'; + } + ObLobCommon header_; + char json_bin_[4]; +}; + } // sql } // oceanbase #endif // OCEANBASE_SQL_OB_EXPR_JSON_FUNC_HELPER_H_ \ No newline at end of file diff --git a/src/storage/lob/ob_lob_manager.cpp b/src/storage/lob/ob_lob_manager.cpp index 1599f2e1ec..036bdd92dd 100644 --- a/src/storage/lob/ob_lob_manager.cpp +++ b/src/storage/lob/ob_lob_manager.cpp @@ -25,6 +25,8 @@ namespace oceanbase namespace storage { +const ObLobCommon ObLobManager::ZERO_LOB = ObLobCommon(); + int ObLobManager::mtl_new(ObLobManager *&m) { int ret = OB_SUCCESS; const uint64_t tenant_id = MTL_ID(); diff --git a/src/storage/lob/ob_lob_manager.h b/src/storage/lob/ob_lob_manager.h index f7eeece0f4..0e82c3b49c 100644 --- a/src/storage/lob/ob_lob_manager.h +++ b/src/storage/lob/ob_lob_manager.h @@ -141,6 +141,7 @@ public: static const uint64_t LOB_READ_BUFFER_LEN = 1024L*1024L; // 1M static const int64_t LOB_IN_ROW_MAX_LENGTH = 4096; // 4K static const uint64_t REMOTE_LOB_QUERY_RETRY_MAX = 10L; // 1M + static const ObLobCommon ZERO_LOB; // static empty lob for zero val private: explicit ObLobManager(const uint64_t tenant_id) : tenant_id_(tenant_id),