问题现象
OceanBase 数据库 V4.2.1 集群中执行如下格式的 insert 语句时,出现非预期的列长度不匹配异常,异常所提示的列实际并未超出限制,手动执行一般无法复现。
-- SQL 语句。
insert into x select * from(select 0, 0 from dual)v
insert into x select * from(select 0, 1 from dual)v
-- SQL 语句执行报错。
ORA-12899: value too large for column "xxxx"."zzzz"."dddd" (actual: 2, maximum: 1)
同时出现如下日志。
[2024-10-19 18:56:53.361114] WDIAG [SQL] string_length_check (ob_datum_cast.cpp:9552) [698620][T1050_L0_G0][T1050][xxxxx-xxxxx-xxxxx-xxxxx] [lt=29][errcode=0] char type length is too long(str_len_byte=2, max_len_byte=1)
[2024-10-19 18:56:53.361137] WDIAG [SQL] string_length_check (ob_datum_cast.cpp:9599) [698620][T1050_L0_G0][T1050][xxxxx-xxxxx-xxxxx-xxxxx] [lt=21][errcode=0] string accuracy check failed(cast_ret=-5167, ret=0, warning=-5167, is_oracle=true, meta={type:"CHAR", collation:"utf8mb4_bin", coercibility:"INVALID"})
[2024-10-19 18:56:53.361161] WDIAG [SQL.ENG] column_convert_datum_accuracy_check (ob_expr_column_conv.cpp:346) [698620][T1050_L0_G0][T1050][xxxxx-xxxxx-xxxxx-xxxxx] [lt=20][errcode=-5167] fail to check accuracy(ret=-5167, expr={type:"T_FUN_COLUMN_CONV", datum_meta:{type:"CHAR", cs_type:"utf8mb4_bin", scale:-1, precision:2}, obj_meta:{type:"CHAR", collation:"utf8mb4_bin", coercibility:"IMPLICIT"}, obj_datum_map:1, flag:3, eval_func:0x55f1951de610, eval_batch_func:0x55f19d7c21f0, inner_functions:null, inner_func_cnt:0, arg_cnt:6, parent_cnt:0, frame_idx:2, datum_off:9400, res_buf_off:47684, dyn_buf_header_offset:26132, res_buf_len:1, eval_flags_off:18628, pvt_skip_off:9592, expr_ctx_id:4294967295, extra:0, batch_idx_mask:18446744073709551615, this:0x7f993de6e610}, warning=-5167)
问题原因
该问题为 OceanBase 数据库内部 SQL 执行缺陷,该缺陷导致此类 SQL 在内部处理时某些列的值被错误的进行了赋值,从而导致此非预期报错。
问题的风险及影响
SQL 执行异常以及数据正确性问题。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V4.x 版本。
解决方法及规避方式
解决方法:
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V4.2.1 BP8(oceanbase-4.2.1.8-108000052024072217)及之后版本。
规避方式:
将 select 中的常量输出列全部添加唯一别名解决。