[CP] Improve incorrect value error info for insert/replace into values
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
#include "sql/engine/expr/ob_expr_type_to_str.h"
|
||||
#include "sql/engine/px/ob_dfo.h"
|
||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||
#include "sql/engine/dml/ob_dml_service.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -81,6 +82,7 @@ int ObExprValuesSpec::serialize(char *buf,
|
||||
OB_UNIS_ENCODE(err_log_ct_def_);
|
||||
OB_UNIS_ENCODE(contain_ab_param_);
|
||||
OB_UNIS_ENCODE(ins_values_batch_opt_);
|
||||
OB_UNIS_ENCODE(column_names_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +106,7 @@ OB_DEF_SERIALIZE_SIZE(ObExprValuesSpec)
|
||||
OB_UNIS_ADD_LEN(err_log_ct_def_);
|
||||
OB_UNIS_ADD_LEN(contain_ab_param_);
|
||||
OB_UNIS_ADD_LEN(ins_values_batch_opt_);
|
||||
OB_UNIS_ADD_LEN(column_names_);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -116,6 +119,7 @@ OB_DEF_SERIALIZE(ObExprValuesSpec)
|
||||
OB_UNIS_ENCODE(err_log_ct_def_);
|
||||
OB_UNIS_ENCODE(contain_ab_param_);
|
||||
OB_UNIS_ENCODE(ins_values_batch_opt_);
|
||||
OB_UNIS_ENCODE(column_names_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -128,6 +132,7 @@ OB_DEF_DESERIALIZE(ObExprValuesSpec)
|
||||
OB_UNIS_DECODE(err_log_ct_def_);
|
||||
OB_UNIS_DECODE(contain_ab_param_);
|
||||
OB_UNIS_DECODE(ins_values_batch_opt_);
|
||||
OB_UNIS_DECODE(column_names_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -174,7 +179,7 @@ int64_t ObExprValuesSpec::get_serialize_size_(const ObPhyOpSeriCtx &seri_ctx) co
|
||||
OB_UNIS_ADD_LEN(err_log_ct_def_);
|
||||
OB_UNIS_ADD_LEN(contain_ab_param_);
|
||||
OB_UNIS_ADD_LEN(ins_values_batch_opt_);
|
||||
|
||||
OB_UNIS_ADD_LEN(column_names_);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -447,6 +452,7 @@ OB_INLINE int ObExprValuesOp::calc_next_row()
|
||||
}
|
||||
while (OB_SUCC(ret) && node_idx_ < real_value_cnt && !is_break) {
|
||||
int64_t real_node_idx = node_idx_ % MY_SPEC.get_value_count();
|
||||
int64_t row_num = real_node_idx / col_num + 1;
|
||||
ObExpr *src_expr = MY_SPEC.values_.at(real_node_idx);
|
||||
ObExpr *dst_expr = MY_SPEC.output_.at(col_idx);
|
||||
ObDatumMeta src_meta = src_expr->datum_meta_;
|
||||
@ -547,6 +553,8 @@ OB_INLINE int ObExprValuesOp::calc_next_row()
|
||||
if (OB_FAIL(datum_caster_.to_type(dst_expr->datum_meta_, str_values,
|
||||
real_src_expr, cm_, datum))) {
|
||||
LOG_WARN("fail to do to_type", K(ret), K(*dst_expr), K(real_src_expr));
|
||||
ObString column_name = MY_SPEC.column_names_.at(col_idx);
|
||||
ret = ObDMLService::log_user_error_inner(ret, row_num, column_name, ctx_);
|
||||
}
|
||||
}
|
||||
} else if (!dst_expr->obj_meta_.is_lob_storage()) {
|
||||
@ -558,6 +566,8 @@ OB_INLINE int ObExprValuesOp::calc_next_row()
|
||||
ret = OB_ERR_CANT_CREATE_GEOMETRY_OBJECT;
|
||||
LOG_USER_WARN(OB_ERR_CANT_CREATE_GEOMETRY_OBJECT);
|
||||
}
|
||||
ObString column_name = MY_SPEC.column_names_.at(col_idx);
|
||||
ret = ObDMLService::log_user_error_inner(ret, row_num, column_name, ctx_);
|
||||
}
|
||||
} else { // dst type is lob
|
||||
if (OB_FAIL(eval_values_op_dynamic_cast_to_lob(real_src_expr, src_obj_meta, dst_expr))) {
|
||||
|
||||
@ -31,6 +31,7 @@ public:
|
||||
ObExprValuesSpec(common::ObIAllocator &alloc, const ObPhyOperatorType type)
|
||||
: ObOpSpec(alloc, type),
|
||||
values_(alloc),
|
||||
column_names_(alloc),
|
||||
is_strict_json_desc_(alloc),
|
||||
str_values_array_(alloc),
|
||||
err_log_ct_def_(alloc),
|
||||
@ -50,6 +51,7 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprValuesSpec);
|
||||
public:
|
||||
common::ObFixedArray<ObExpr *, common::ObIAllocator> values_;
|
||||
common::ObFixedArray<common::ObString, common::ObIAllocator> column_names_;
|
||||
common::ObFixedArray<bool, common::ObIAllocator> is_strict_json_desc_;
|
||||
common::ObFixedArray<ObStrValues, common::ObIAllocator> str_values_array_;
|
||||
ObErrLogCtDef err_log_ct_def_;
|
||||
|
||||
@ -58,7 +58,8 @@ int ObDMLService::check_row_null(const ObExprPtrIArray &row,
|
||||
const bool is_nullable = column_infos.at(i).is_nullable_;
|
||||
uint64_t col_idx = column_infos.at(i).projector_index_;
|
||||
if (OB_FAIL(row.at(col_idx)->eval(eval_ctx, datum))) {
|
||||
dml_op.log_user_error_inner(ret, row_num, column_infos.at(i));
|
||||
common::ObString column_name = column_infos.at(i).column_name_;
|
||||
ret = ObDMLService::log_user_error_inner(ret, row_num, column_name, dml_op.get_exec_ctx());
|
||||
} else if (!is_nullable && datum->is_null()) {
|
||||
if (is_ignore ||
|
||||
(lib::is_mysql_mode() && !is_single_value && !is_strict_mode(session->get_sql_mode()))) {
|
||||
@ -118,7 +119,8 @@ int ObDMLService::check_column_type(const ExprFixedArray &dml_row,
|
||||
ObExpr *expr = dml_row.at(column_info.projector_index_);
|
||||
ObDatum *datum = nullptr;
|
||||
if (OB_FAIL(expr->eval(dml_op.get_eval_ctx(), datum))) {
|
||||
dml_op.log_user_error_inner(ret, row_num, column_info);
|
||||
common::ObString column_name = column_infos.at(i).column_name_;
|
||||
ret = ObDMLService::log_user_error_inner(ret, row_num, column_name, dml_op.get_exec_ctx());
|
||||
} else if (!datum->is_null() && expr->obj_meta_.is_geometry()) {
|
||||
// geo column type
|
||||
const uint32_t column_srid = column_info.srs_info_.srid_;
|
||||
@ -2198,5 +2200,82 @@ int ObDMLService::handle_after_row_processing(bool execute_single_row, ObDMLModi
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDMLService::log_user_error_inner(
|
||||
int ret,
|
||||
int64_t row_num,
|
||||
common::ObString &column_name,
|
||||
ObExecContext &ctx)
|
||||
{
|
||||
if (OB_DATA_OUT_OF_RANGE == ret) {
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(OB_DATA_OUT_OF_RANGE, column_name.length(), column_name.ptr(), row_num);
|
||||
} else if (OB_ERR_DATA_TOO_LONG == ret && lib::is_mysql_mode()) {
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(OB_ERR_DATA_TOO_LONG, column_name.length(), column_name.ptr(), row_num);
|
||||
} else if (OB_ERR_VALUE_LARGER_THAN_ALLOWED == ret) {
|
||||
LOG_USER_ERROR(OB_ERR_VALUE_LARGER_THAN_ALLOWED);
|
||||
} else if (OB_INVALID_DATE_VALUE == ret || OB_INVALID_DATE_FORMAT == ret) {
|
||||
ret = OB_INVALID_DATE_VALUE;
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_INVALID_DATE_MSG_FMT_V2,
|
||||
column_name.length(),
|
||||
column_name.ptr(),
|
||||
row_num);
|
||||
} else if ((OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD == ret || OB_INVALID_NUMERIC == ret)
|
||||
&& lib::is_mysql_mode()) {
|
||||
ret = OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD;
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
column_name.length(),
|
||||
column_name.ptr(),
|
||||
row_num);
|
||||
} else if (OB_ERR_WARN_DATA_OUT_OF_RANGE == ret && lib::is_mysql_mode()) {
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(OB_ERR_WARN_DATA_OUT_OF_RANGE, column_name.length(), column_name.ptr(), row_num);
|
||||
} else if ((OB_ERR_DATA_TRUNCATED == ret || OB_ERR_DOUBLE_TRUNCATED == ret)
|
||||
&& lib::is_mysql_mode()) {
|
||||
ret = OB_ERR_DATA_TRUNCATED;
|
||||
ob_reset_tsi_warning_buffer();
|
||||
ObSQLUtils::copy_and_convert_string_charset(
|
||||
ctx.get_allocator(),
|
||||
column_name,
|
||||
column_name,
|
||||
CS_TYPE_UTF8MB4_BIN,
|
||||
ctx.get_my_session()->get_local_collation_connection());
|
||||
LOG_USER_ERROR(OB_ERR_DATA_TRUNCATED, column_name.length(), column_name.ptr(), row_num);
|
||||
} else {
|
||||
LOG_WARN("fail to operate row", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
@ -235,6 +235,10 @@ public:
|
||||
static int add_trans_info_datum(ObExpr *trans_info_expr,
|
||||
ObEvalCtx &eval_ctx,
|
||||
ObChunkDatumStore::StoredRow *stored_row);
|
||||
static int log_user_error_inner(int ret,
|
||||
int64_t row_num,
|
||||
common::ObString &column_name,
|
||||
ObExecContext &ctx);
|
||||
|
||||
private:
|
||||
template <int N>
|
||||
|
||||
@ -1017,56 +1017,6 @@ OperatorOpenOrder ObTableModifyOp::get_operator_open_order() const
|
||||
return open_order;
|
||||
}
|
||||
|
||||
void ObTableModifyOp::log_user_error_inner(int ret, int64_t col_idx, int64_t row_num,
|
||||
const ObIArray<ColumnContent> &column_infos) const
|
||||
{
|
||||
if (OB_DATA_OUT_OF_RANGE == ret &&
|
||||
(0 <= col_idx && col_idx < column_infos.count())) {
|
||||
ObString column_name = column_infos.at(col_idx).column_name_;
|
||||
LOG_USER_ERROR(OB_DATA_OUT_OF_RANGE, column_name.length(), column_name.ptr(), row_num);
|
||||
} else if (OB_ERR_DATA_TOO_LONG == ret &&
|
||||
(0 <= col_idx && col_idx < column_infos.count())) {
|
||||
ObString column_name = column_infos.at(col_idx).column_name_;
|
||||
if (lib::is_mysql_mode()) {
|
||||
//for error code OB_ERR_DATA_TOO_LONG, oracle and mysql has the different error msg
|
||||
//oracle error msg has output in ObExprColumnConv, so need to skip oracle mode here
|
||||
LOG_USER_ERROR(OB_ERR_DATA_TOO_LONG, column_name.length(), column_name.ptr(), row_num);
|
||||
}
|
||||
} else if (OB_ERR_VALUE_LARGER_THAN_ALLOWED == ret && col_idx >= 0) {
|
||||
LOG_USER_ERROR(OB_ERR_VALUE_LARGER_THAN_ALLOWED);
|
||||
} else if ((OB_INVALID_DATE_VALUE == ret || OB_INVALID_DATE_FORMAT == ret)
|
||||
&& (0 <= col_idx && col_idx < column_infos.count())) {
|
||||
ObString column_name = column_infos.at(col_idx).column_name_;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_DATE_MSG_FMT_V2, column_name.length(),
|
||||
column_name.ptr(), row_num);
|
||||
} else {
|
||||
LOG_WARN("fail to operate row", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
void ObTableModifyOp::log_user_error_inner(int ret, int64_t row_num, const ColumnContent &column_info) const
|
||||
{
|
||||
if (OB_DATA_OUT_OF_RANGE == ret) {
|
||||
ObString column_name = column_info.column_name_;
|
||||
LOG_USER_ERROR(OB_DATA_OUT_OF_RANGE, column_name.length(), column_name.ptr(), row_num);
|
||||
} else if (OB_ERR_DATA_TOO_LONG == ret) {
|
||||
ObString column_name = column_info.column_name_;
|
||||
if (lib::is_mysql_mode()) {
|
||||
//for error code OB_ERR_DATA_TOO_LONG, oracle and mysql has the different error msg
|
||||
//oracle error msg has output in ObExprColumnConv, so need to skip oracle mode here
|
||||
LOG_USER_ERROR(OB_ERR_DATA_TOO_LONG, column_name.length(), column_name.ptr(), row_num);
|
||||
}
|
||||
} else if (OB_ERR_VALUE_LARGER_THAN_ALLOWED == ret) {
|
||||
LOG_USER_ERROR(OB_ERR_VALUE_LARGER_THAN_ALLOWED);
|
||||
} else if (OB_INVALID_DATE_VALUE == ret || OB_INVALID_DATE_FORMAT == ret) {
|
||||
ObString column_name = column_info.column_name_;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_DATE_MSG_FMT_V2, column_name.length(),
|
||||
column_name.ptr(), row_num);
|
||||
} else {
|
||||
LOG_WARN("fail to operate row", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
int ObTableModifyOp::submit_all_dml_task()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
@ -210,9 +210,6 @@ public:
|
||||
bool is_fk_root_session();
|
||||
const ObObjPrintParams &get_obj_print_params() { return obj_print_params_; }
|
||||
int init_foreign_key_operation();
|
||||
void log_user_error_inner(int ret, int64_t col_idx, int64_t row_num,
|
||||
const ObIArray<ColumnContent> &column_infos) const;
|
||||
void log_user_error_inner(int ret, int64_t row_num, const ColumnContent &column_info) const;
|
||||
void clear_dml_evaluated_flag();
|
||||
void clear_dml_evaluated_flag(int64_t parent_cnt, ObExpr **parent_exprs);
|
||||
void clear_dml_evaluated_flag(ObExpr *clear_expr);
|
||||
|
||||
Reference in New Issue
Block a user