diff --git a/src/share/object/ob_obj_cast.cpp b/src/share/object/ob_obj_cast.cpp index 423364c76a..939e57062a 100644 --- a/src/share/object/ob_obj_cast.cpp +++ b/src/share/object/ob_obj_cast.cpp @@ -14343,30 +14343,14 @@ int ObObjCaster::to_type(const ObExpectType &expect_type, const char OB_JSON_NULL[2] = {'\0', '\0'}; // binary json null -int ObObjCaster::get_zero_value(const ObObjType expect_type, - ObCollationType expect_cs_type, - int64_t data_len, - ObIAllocator &alloc, - ObObj &zero_obj) +int ObObjCaster::get_zero_value(const ObObjType expect_type, ObCollationType expect_cs_type, ObObj &zero_obj) { int ret = OB_SUCCESS; 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)) { - //zero_obj.set_string(expect_type, ""); - ObString padding_res; - if (ObVarcharType == expect_type) { - zero_obj.set_string(expect_type, ""); - } else if (0 > data_len) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("The length of fix-len string is less than zero", K(ret), K(data_len)); - } else if (OB_FAIL(sql::padding_char_for_cast(data_len, expect_cs_type, alloc, - padding_res))) { - LOG_WARN("padding char failed", K(ret), K(data_len), K(expect_cs_type)); - } else { - zero_obj.set_string(expect_type, padding_res); - } + if (ob_is_string_tc(expect_type) || ob_is_text_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); } else if (ob_is_int_tc(expect_type)) { diff --git a/src/share/object/ob_obj_cast.h b/src/share/object/ob_obj_cast.h index 3d628b6ce9..49c3ecd5b3 100644 --- a/src/share/object/ob_obj_cast.h +++ b/src/share/object/ob_obj_cast.h @@ -400,11 +400,7 @@ public: const ObObj &in_obj, ObObj &out_obj); static int to_type(const ObObjType expect_type, ObCollationType expect_cs_type, ObCastCtx &cast_ctx, const ObObj &in_obj, ObObj &out_obj); - static int get_zero_value(const ObObjType expect_type, - ObCollationType expect_cs_type, - int64_t data_len, - ObIAllocator &alloc, - ObObj &zero_obj); + static int get_zero_value(const ObObjType expect_type, ObCollationType expect_cs_type, ObObj &zero_obj); static int enumset_to_inner(const ObObjMeta &expect_meta, const ObObj &in_obj, ObObj &out_obj, common::ObIAllocator &allocator, diff --git a/src/sql/das/ob_das_utils.cpp b/src/sql/das/ob_das_utils.cpp index a69271c130..2da0921197 100644 --- a/src/sql/das/ob_das_utils.cpp +++ b/src/sql/das/ob_das_utils.cpp @@ -257,10 +257,23 @@ int ObDASUtils::reshape_storage_value(const ObObjMeta &col_type, const ObAccuracy &col_accuracy, ObIAllocator &allocator, ObObj &value) +{ + int ret = OB_SUCCESS; + if (lib::is_oracle_mode() && value.is_character_type() && value.get_string_len() == 0) { + // Oracle compatibility mode: '' as null + LOG_DEBUG("reshape empty string to null", K(value)); + value.set_null(); + } else if (OB_FAIL(padding_fixed_string_value(col_accuracy.get_length(), allocator, value))) { + LOG_WARN("padding char value failed", K(ret), K(col_accuracy), K(value)); + } + return ret; +} + +int ObDASUtils::padding_fixed_string_value(int64_t max_len, ObIAllocator &allocator, ObObj &value) { int ret = OB_SUCCESS; if (value.is_binary()) { - int32_t binary_len = col_accuracy.get_length(); + int32_t binary_len = max_len; int32_t len = value.get_string_len(); if (binary_len > len) { char *dest_str = NULL; @@ -275,10 +288,6 @@ int ObDASUtils::reshape_storage_value(const ObObjMeta &col_type, value.set_binary(ObString(binary_len, dest_str)); } } - } else if (lib::is_oracle_mode() && value.is_character_type() && value.get_string_len() == 0) { - // Oracle compatibility mode: '' as null - LOG_DEBUG("reshape empty string to null", K(value)); - value.set_null(); } else if (value.is_fixed_len_char_type()) { const char *str = value.get_string_ptr(); int32_t len = value.get_string_len(); diff --git a/src/sql/das/ob_das_utils.h b/src/sql/das/ob_das_utils.h index 540fe40344..16d770be78 100644 --- a/src/sql/das/ob_das_utils.h +++ b/src/sql/das/ob_das_utils.h @@ -62,6 +62,7 @@ public: const bool enable_oracle_empty_char_reshape_to_null, ObIAllocator &allocator, blocksstable::ObStorageDatum &datum_value); + static int padding_fixed_string_value(int64_t max_len, ObIAllocator &alloc, ObObj &value); static int generate_spatial_index_rows(ObIAllocator &allocator, const ObDASDMLBaseCtDef &das_ctdef, const ObString &wkb_str, diff --git a/src/sql/engine/dml/ob_dml_service.cpp b/src/sql/engine/dml/ob_dml_service.cpp index e043050b9d..51b5725d7d 100644 --- a/src/sql/engine/dml/ob_dml_service.cpp +++ b/src/sql/engine/dml/ob_dml_service.cpp @@ -39,15 +39,14 @@ using namespace transaction; namespace sql { int ObDMLService::check_row_null(const ObExprPtrIArray &row, - ObEvalCtx &eval_ctx, - int64_t row_num, - const ColContentIArray &column_infos, - const ObDASDMLBaseCtDef &das_ctdef, - bool is_single_value, - ObTableModifyOp &dml_op) + ObEvalCtx &eval_ctx, + int64_t row_num, + const ColContentIArray &column_infos, + bool is_ignore, + bool is_single_value, + ObTableModifyOp &dml_op) { int ret = OB_SUCCESS; - const bool is_ignore = das_ctdef.is_ignore_; ObSQLSessionInfo *session = NULL; CK(row.count() >= column_infos.count()); if (OB_ISNULL(session = dml_op.get_exec_ctx().get_my_session())) { @@ -65,6 +64,7 @@ int ObDMLService::check_row_null(const ObExprPtrIArray &row, if (is_ignore || (lib::is_mysql_mode() && !is_single_value && !is_strict_mode(session->get_sql_mode()))) { ObObj zero_obj; + ObExprStrResAlloc res_alloc(*row.at(col_idx), eval_ctx); ObDatum &row_datum = row.at(col_idx)->locate_datum_for_write(eval_ctx); bool is_decimal_int = ob_is_decimal_int(row.at(col_idx)->datum_meta_.type_); if (is_oracle_mode()) { @@ -77,8 +77,6 @@ int ObDMLService::check_row_null(const ObExprPtrIArray &row, } else if (OB_FAIL(ObObjCaster::get_zero_value( row.at(col_idx)->obj_meta_.get_type(), row.at(col_idx)->obj_meta_.get_collation_type(), - das_ctdef.column_accuracys_.at(col_idx).get_length(), - eval_ctx.exec_ctx_.get_allocator(), zero_obj))) { LOG_WARN("get column default zero value failed", K(ret), K(column_infos.at(i)), K(row.at(col_idx)->max_length_)); } else if (is_decimal_int) { @@ -88,6 +86,11 @@ int ObDMLService::check_row_null(const ObExprPtrIArray &row, row_datum.set_decimal_int(dec_val.get_decimal_int(), dec_val.get_int_bytes()); } if (OB_FAIL(ret)) { + LOG_WARN("get column default zero value failed", K(ret), K(column_infos.at(i))); + } else if (OB_FAIL(ObDASUtils::padding_fixed_string_value(row.at(col_idx)->max_length_, + 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))) { @@ -613,7 +616,7 @@ int ObDMLService::process_insert_row(const ObInsCtDef &ins_ctdef, dml_op.get_eval_ctx(), ins_rtdef.cur_row_num_, ins_ctdef.column_infos_, - ins_ctdef.das_ctdef_, + ins_ctdef.das_ctdef_.is_ignore_, ins_ctdef.is_single_value_, dml_op))) { LOG_WARN("check row null failed", K(ret)); @@ -829,7 +832,7 @@ int ObDMLService::process_update_row(const ObUpdCtDef &upd_ctdef, dml_op.get_eval_ctx(), upd_rtdef.cur_row_num_, upd_ctdef.assign_columns_, - upd_ctdef.dupd_ctdef_, + upd_ctdef.dupd_ctdef_.is_ignore_, false, dml_op))) { LOG_WARN("check row null failed", K(ret), K(upd_ctdef), K(upd_rtdef)); diff --git a/src/sql/engine/dml/ob_dml_service.h b/src/sql/engine/dml/ob_dml_service.h index fa2805debe..6349057d81 100644 --- a/src/sql/engine/dml/ob_dml_service.h +++ b/src/sql/engine/dml/ob_dml_service.h @@ -28,7 +28,7 @@ public: ObEvalCtx &eval_ctx, int64_t row_num, const ColContentIArray &column_infos, - const ObDASDMLBaseCtDef &das_ctdef, + bool is_ignore, bool is_single_value, ObTableModifyOp &dml_op); static int check_column_type(const ExprFixedArray &dml_row, diff --git a/tools/deploy/mysql_test/test_suite/update/r/mysql/update_ignore.result b/tools/deploy/mysql_test/test_suite/update/r/mysql/update_ignore.result index 964af576ea..b58b3b1224 100644 Binary files a/tools/deploy/mysql_test/test_suite/update/r/mysql/update_ignore.result and b/tools/deploy/mysql_test/test_suite/update/r/mysql/update_ignore.result differ diff --git a/tools/deploy/mysql_test/test_suite/update/t/update_ignore.test b/tools/deploy/mysql_test/test_suite/update/t/update_ignore.test index 9b8f079292..167b786d20 100644 --- a/tools/deploy/mysql_test/test_suite/update/t/update_ignore.test +++ b/tools/deploy/mysql_test/test_suite/update/t/update_ignore.test @@ -154,3 +154,97 @@ select * from z0case; UPDATE Z0CASE SET T1='AbC' WHERE T2='11'; select * from z0case; drop table z0case; + +--disable_warnings +drop table if exists table0_innodb_key_pk_parts_2; + +CREATE TABLE table0_innodb_key_pk_parts_2 ( +col_bit bit, +col_blob blob, +col_char_key char (1), +col_blob_not_null blob not null, +col_int_not_null_key int not null, +col_float_not_null float not null, +col_bit_not_null bit not null, +col_decimal_not_null_key decimal not null, +col_decimal decimal, +col_set_not_null set ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') not null, +col_bit_not_null_key bit not null, +col_int_key int, +col_char_not_null_key char (1) not null, +col_int_unsigned_not_null_key int unsigned not null, +col_decimal_not_null decimal not null, +col_bit_key bit, +col_set_not_null_key set ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') not null, +col_set_key set ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'), +col_enum_not_null enum ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') not null, +col_float_unsigned_not_null_ke float unsigned not null, +col_int_unsigned_key int unsigned, +col_int_unsigned int unsigned, +col_int_not_null int not null, +col_float float, +col_char char (1), +col_decimal_unsigned decimal unsigned, +col_enum_not_null_key enum ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') not null, +col_set set ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'), +col_decimal_unsigned_key decimal unsigned, +col_char_not_null char (1) not null, +col_float_unsigned_not_null float unsigned not null, +pk int, +col_decimal_unsigned_not_null decimal unsigned not null, +col_decimal_unsigned_not_null_ decimal unsigned not null, +col_float_key float, +col_float_not_null_key float not null, +col_blob_not_null_key blob not null, +col_decimal_key decimal, +col_int int, +col_enum_key enum ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'), +col_blob_key blob, +col_enum enum ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'), +col_float_unsigned float unsigned, +col_float_unsigned_key float unsigned, +col_int_unsigned_not_null int unsigned not null, +/*Indices*/ +key idx13(col_char_key ), +key idx9(col_int_not_null_key ), +key idx41(col_decimal_not_null_key ), +key idx3(col_bit_not_null_key ), +key idx5(col_int_key ), +key idx15(col_char_not_null_key ), +key idx11(col_int_unsigned_not_null_key ), +key idx1(col_bit_key ), +key idx23(col_set_not_null_key ), +key idx21(col_set_key ), +key idx35(col_float_unsigned_not_null_ke ), +key idx7(col_int_unsigned_key ), +key idx19(col_enum_not_null_key ), +key idx39(col_decimal_unsigned_key ), +key idx43(col_decimal_unsigned_not_null_ ), +key idx29(col_float_key ), +key idx33(col_float_not_null_key ), +key idx27(col_blob_not_null_key (255)), +key idx37(col_decimal_key ), +key idx17(col_enum_key ), +key idx25(col_blob_key (255)), +key idx31(col_float_unsigned_key )) ENGINE=innodb PARTITION BY key (pk) partitions 2; + +set sql_mode = ''; + +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_blob_not_null , col_float , col_float_unsigned_not_null_ke ) VALUES ( '2009-06-17 02:00:49' , '2008-05-04 09:58:22.031383' , -24420 ); +--error 1048 +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_decimal_key , col_set_not_null , col_bit_not_null_key ) VALUES ( '2002-08-21 15:50:49' , NULL , '2008-04-08 00:54:35.035855' ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_decimal_unsigned_not_null , col_set_key , col_enum_key ) VALUES ( 4 , -4338432 , '05:31:13' ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_char_not_null_key , col_enum_not_null , col_enum ) VALUES ( '2003-06-24 04:26:58.057298' , 'arzwkjqshciwulehkuyzewxtpbpfmfj' , '2003' ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_decimal_unsigned , col_int_key , col_float ) VALUES ( 'lq' , '2005' , '2003-06-11 10:08:30' ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_char_not_null , col_char , col_int_not_null_key ) VALUES ( 8 , -7474944 , 896512 ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_bit_not_null_key , col_blob_not_null , pk ) VALUES ( '20:58:15' , 'hrzplcvmxggypuvoppkxwfvkhchskzmiwiombucu' , 30604 ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_float_unsigned_not_null_ke , col_char_key , col_char ) VALUES ( '2008' , '2001' , 3 ); +--error 1048 +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_enum_not_null_key , col_decimal_unsigned_not_null_ , col_blob ) VALUES ( 26681 , NULL , 14465 ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_enum , col_enum_not_null , col_decimal ) VALUES ( '2006-04-09 05:33:14.045216' , '2008' , '2004-09-17 09:11:54.004359' ); +INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ INTO table0_innodb_key_pk_parts_2 ( col_blob_key , col_int_unsigned_not_null , col_int_not_null_key ) VALUES ( '20:35:45' , 47682 , 1319 ); + +UPDATE /*+ ENABLE_PARALLEL_DML PARALLEL(3) */ table0_innodb_key_pk_parts_2 SET col_blob_not_null_key = NULL WHERE col_bit_not_null <> '08:59:21'; +select * from table0_innodb_key_pk_parts_2; +drop table table0_innodb_key_pk_parts_2; +--enable_warnings